Предварительные требования
public class A { }
public class B extends A { }
public class C extends A { }
List<A> listA = new ArrayList<A>();
List<B> listB = new ArrayList<B>();
Проблема
listB = listA; //not compiled
listA = listB; //not compiled
listB = listA;
В списке A вы можете вставить объекты, которые являются экземплярами A или подклассами A (B и C). Тогда вы могли бы рискнуть, что listA
содержит не-B объекты. Затем, когда вы попытаетесь извлечь объекты из listB
, вы рискуете получить объекты, не относящиеся к B (например, A или C). Это нарушает договор объявления переменной listB
.
listA = listB;
Если бы вы могли сделать это назначение, можно было бы вставить экземпляров A и C в список, на который указывает listB
. Вы можете сделать это с помощью ссылки listA
, которая объявлена как List. Таким образом, вы можете вставить объекты не-B в список, объявленный для хранения экземпляров B (или подкласса B).
Цель
При создании многократно используемых методов, которые работают с коллекциями
определенный тип.
Вам следует использовать List <? extends A>
( верхняя граница ), если вы собираетесь читать .get () из списка
Когда вы знаете, что экземпляры в коллекции являются экземплярами A или подклассами A, безопасно читать экземпляры коллекции и приводить их к экземплярам A.
Вы не можете вставить элементы в список, потому что вы не знаете, относится ли список к классу A, B или C.
Вам следует использовать List <? super A>
( нижняя граница ), если вы собираетесь вставить .add () в список
Когда вы знаете, что список типизирован либо для A, либо для суперкласса A, безопасно вставить экземпляров A или подклассов A (например, B или C) в список. 1059 *
Вы не можете прочитать из списка, за исключением случаев, когда он переводит прочитанные объекты в Object. Элементы, уже присутствующие в списке, могут относиться к любому типу, который является либо A, либо суперклассом A, но невозможно точно знать, какой это класс.
Пожалуйста Подробнее читайте здесь - http://tutorials.jenkov.com/java-generics/wildcards.html