Если я не ошибаюсь, вы хотите иметь объяснение о том, как это ниже правильный код:
List<Number> nums = new ArrayList<Number>();
List<? super Number> sink = nums;
Инвариантность является свойством класса о том, как его параметр типа влияет на его подтипов.
Дженерики являются инвариантными, но существуют дикие карты, которые помогают нам с подтипами. Они не очень полезны, поскольку они не представляют никакого типа, но представляют собой хороший взлом.Ниже действует
List<Animal> <: List<?>
List<?> <: List
Лучше пример:
List<? super Animal> d1= new ArrayList<Animal>();
d1.add(new Animal());
d1.add(new Dog());
Вышеуказанные работы, потому что d1
имеет тип List<? super Animal>
. Вы можете представить себе add
функцию вести себя, как:
boolean add(? super Animal e);
Так add
метод можно передать любую переменную, которая подтип из ? super Animal
. И
Animal <: ? super Animal
Dog <: ? super Animal
Так что добавление собаки или животных работает. Таким образом, d1
действует как список, который может принимать любой параметр типа Animal
или подтип, если он.
Аналогичным образом, вы также можете иметь ниже. Но технически вы не можете ничего добавить в этот список. Если в java существовал sometype, который является подтипом каждого типа, тогда вы можете правильно добавить к нему элемент этого типа. Ничего больше.
ArrayList<? extends Animal> d1 = new ArrayList<Animal>();
Посмотрите на этот ответ для получения более info.
Я не уверен, что понимаю, о чем вы спрашиваете. Третья строка кода, которая у вас есть, является недопустимым синтаксисом. – Makoto
Взгляните на [PECS] (http://stackoverflow.com/questions/2723397/java-generics-what-is-pecs). –
Не могу сказать, что вы пытаетесь спросить. * "скажем, если wildcard является Object, поэтому строка 2 wil be" * 'List