
В качестве Type могут выступать классы, интерфейсы и enum.
List<? super Integer> listInt = new ArrayList<Integer>();
List<? super Integer> listDouble = new ArrayList<Number>();
List<? super Integer> listDouble = new ArrayList<Object>();
List<? super Integer> listStr = new ArrayList<String>(); // ошибка компиляции
Внимание! Через ссылочные переменные, ограниченные снизу, можно добавлять новые элементы только типа Type или его подклассов!
class Gift{ }
class Book extends Gift{ }
class Phone extends Gift{ }
List<? super Gift> list = new ArrayList<Gift>();
list.add(new Gift());
list.add(new Book());
list.add(new Phone());
//list.add(new Object()); // ошибка компиляции
Переменные, которые будут ссылаться на объекты из ограниченного снизу списка, должны быть типа Object, либо явно приведены к типу Type.
Object gift = list.get(0);
Gift book = (Book)list.get(1);
Phone phone = (Phone)list.get(2);
// Phone phone = list.get(2); // ошибка компиляции
Wildcard "?" означает тип Object. "?" уничтожает всю информацию о типе хранящихся объектов. Все элементы списка list имеют тип Object. Поэтому и переменная должна иметь тип Object. Gift указан только для ограничения типов, которые могут быть переданы в список.