Представьте, что это тело метода add
. Это прекрасно компилируется:
static void add(List<? super Z> list){
list.add(new Z() {}); // Fine.
}
Кроме того, это хорошо компилируется.
List<A> aaa= new ArrayList<>();
// ... Something.
A a = aaa.get(0);
Теперь, что если ... Something
:
add(aaa); // Compiler error!
Что произойдет если ошибка компилятора не произошла? ClassCastException
в строке A a = aaa.get(0);
, потому что это экземпляр некоторого подкласса Z
, который не A
.
Попробуйте, вызвав add((List) aaa)
.
This Вот почему компилятор останавливает вас. List<? super Z>
- это список, в который можно безопасно добавлять экземпляры Z
или любой подкласс. List<A>
- это список, в который можно безопасно добавлять экземпляры A
, любого подкласса или нуля; и все, что вы извлекаете из списка, будет A
, подклассом или нулем. Некоторые экземпляры Z
не являются экземплярами A
.