7
public class POJO<T> {

    private List<Integer> integer = new ArrayList<Integer>();

    public POJO() {
        integer.add(1);
        integer.add(2);
    }

    public List<Integer> getInteger() {
        return integer;
    }

    public static void main(String[] args) {
        POJO pojo = new POJO();
        List<String> integer = pojo.getInteger(); // No compile error?
        System.out.println(integer); // prints [1, 2]
    }
}

次の行をコンパイルするにはどうすればよいですか。

List<String> integer = pojo.getInteger();

提供getInteger()されるものは次のように入力されます

public List<Integer> getInteger()
4

3 に答える 3

7

JLS 4.8で、@PeterLawreyの発言を裏付けるリファレンスを見つけました。

スーパークラスまたはスーパーインターフェースから継承されないrawタイプCのコンストラクター(§8.8)、インスタンスメソッド(§8.4、§9.4)、または非静的フィールド(§8.3)Mのタイプは、対応するrawタイプです。 Cに対応する総称宣言のその型の消去に。

したがって、のタイプをPOJO参照しないメソッドを含め、rawオブジェクトのすべてのインスタンスメソッドが消去されます。つまり、(JLS 4.6):TPOJO<T>

[...]メソッドの型パラメーター(§8.4.4)、およびメソッドの戻り型(§8.4.5)も、[...]メソッドのシグネチャが消去されると消去されます。

于 2012-08-31T11:16:23.747 に答える
7

pojoジェネリックとして宣言されていないように

POJO pojo = new POJO();

コンパイラーは、それをプレジェネリックコードで使用していることを前提としています。つまり、コードが記述された後にジェネリックが追加された場合です。だからあなたがするとき

List<String> integer = pojo.getInteger(); 

エラーではなく警告が表示されます。

つまり、タイプが非ジェネリックの場合、指定しなかったタイプに関連するチェックだけでなく、すべてのジェネリックチェックがオフになります。これは、最大限の下位互換性のためだと思います。

比較のために。

Map mapOfInteger = new Map(); // no generics
Set<String> entries = map.entrySet(); // gives a warning, not an error.

この例では、ジェネリックではないと思わSet<Entry<K, V>>れるかもしれませんSet<Entry>が、コンパイラーはクラスを非ジェネリックとして扱うことにフォールバックしSetます。

于 2012-08-31T10:51:43.433 に答える
2

これはチェックされていない割り当てであり、互換性の理由からエラーとして扱われません。

レガシーコードとの相互運用を参照してください

実際には、割り当ては合法ですが、チェックされていない警告が生成されます。

于 2012-08-31T10:57:57.203 に答える