12

次のコード サンプルの場合:

public static class Abc<X> { }
public static class Def<Y> { }
public static class Ghi<Z> { }

public void doThis() {
    List<?> listOne;
    List<Abc<?>> listTwo;
    List<Abc<Def<?>>> listThree;
    List<Abc<Def<Ghi<?>>>> listFour;
    List<Abc<Def<Ghi<String>>>> listFive;

    Abc<Def<Ghi<String>>> abcdef;

    abcdef = new Abc<Def<Ghi<String>>>();

    listOne.add(abcdef);    // line 1
    listTwo.add(abcdef);    // line 2
    listThree.add(abcdef);  // line 3
    listFour.add(abcdef);   // line 4
    listFive.add(abcdef);   // line 5
}

行 1、3、および 4 はコンパイルされません。

(ライン1)

The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (Abc<Def<Ghi<String>>>)

(3行目)

The method add(Abc<Def<?>>) in the type List<Abc<Def<?>>> is not applicable for the arguments (Abc<Def<Ghi<String>>>)

(4行目)

The method add(Abc<Def<Ghi<?>>>) in the type List<Abc<Def<Ghi<?>>>> is not applicable for the arguments (Abc<Def<Ghi<String>>>)

ただし、2 行目と 5 行目はコンパイルされます。

1行目、3行目、4行目が合法的な割り当てではない理由を誰か説明できますか? また、これらの行でワイルドカード パラメータをそのように使用できない場合、なぜ 2 行目の代入が有効なのですか?

4

1 に答える 1

12

listOne.add(abcdef)List<?>(行 1) は、不明な特定のタイプのリストを表しているため、無効です。たとえば、 である可能性があるList<String>ため、 ではないものは追加したくありませんStringAbc<Def<Ghi<String>>>に代入できないため、コンパイラ エラーが発生し?ます。

listTwo.add(abcdef)(2 行目) は、任意の型List<Abc<?>>の のリストを表すため、有効です。そうです -ネストされたワイルドカードは、特定の型ではなく任意の型を表すという点でトップレベルのワイルドカードとは異なります (つまり、ネストされたワイルドカードは をキャプチャしません)。は に代入可能であるため、コンパイラはそれを許可します。ネストされたワイルドカードの詳細については、この投稿を参照してください。汎用メソッドの複数のワイルドカードにより、Java コンパイラ (および私!) が非常に混乱します。AbcAbc<Def<Ghi<String>>>Abc<?>

listThree.add(abcdef)(3 行目) は、任意の型の のリストList<Abc<Def<?>>>を表すため、無効です。ジェネリックは共変ではないため、 に代入可能ですが、 に代入できません。同じ理由で、 a をaに割り当てることはできません。詳細については、この投稿を参照してください: Is List<Dog> a subclass of List<Animal>? Java のジェネリックが暗黙のうちにポリモーフィックではないのはなぜですか?AbcDefAbc<Def<Ghi<String>>>Abc<Def<?>>Def<Ghi<String>>Def<?>List<Integer>List<Number>

listFour.add(abcdef)(4 行目) は同じ理由で無効です -Abc<Def<Ghi<String>>>は に割り当てられませんAbc<Def<Ghi<?>>>

listFive.add(abcdef)(5 行目) は、ジェネリック型が正確に一致するため有効です -Abc<Def<Ghi<String>>>は明らかに に割り当て可能Abc<Def<Ghi<String>>>です。

于 2014-06-19T16:10:45.527 に答える