Подтвердить что ты не робот

Почему ArrayList <ArrayList <? >> list = new ArrayList <ArrayList <String>>() не компилируется?

Почему этот код компилируется

final ArrayList<?> dp1 = new ArrayList<String>();

Но это не

final ArrayList<ArrayList<?>> dp2 = new ArrayList<ArrayList<String>>();
4b9b3361

Ответ 1

В

final ArrayList<?> dp1 = new ArrayList<String>();

Аргумент типа ? является подстановочным знаком, который является надмножеством (не супер-типом) String. Итак, ArrayList<?> является супер-типом ArrayList<String>.

Но в

final ArrayList<ArrayList<?>> dp2 = new ArrayList<ArrayList<String>>();

Аргумент типа ArrayList<?> (параметризованный тип, где ? просто обозначает некоторый тип unkown и не имеет ничего общего с String), не является подстановочным знаком, подстановочный знак будет ? extends ArrayList<?>, с верхней границей ArrayList<?>, которая на самом деле является супертипом ArrayList<String>.

Вы можете прочитать о правилах относительно супер /sub set/type в параметризованном типе здесь.

Ответ 2

Это довольно сложно понять, но в итоге в вашем первом коде String extends ?, но второй не компилируется, потому что ArrayList<String> не наследует напрямую от ArrayList<?>, вы можете посмотреть здесь, если вы хотите получить все детали. Если вы хотите, чтобы ваш второй пример был скомпилирован, вам необходимо изменить его на это:

final ArrayList<? extends ArrayList<?>> dp2 = new ArrayList<ArrayList<String>>();