Я подумал, что у меня есть хорошее понимание дженериков Java.
Этот код НЕ СОСТАВЛЯЕТ и я знаю почему.
Мы можем перейти только к методу тестирования. Список типа Animal или его супертипа (например, List of Objects)
package scjp.examples.generics.wildcards;
import java.util.ArrayList;
import java.util.List;
class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal {}
public class Test {
public void test(List<? super Animal> col) {
col.add(new Animal());
col.add(new Mammal());
col.add(new Dog());
}
public static void main(String[] args) {
List<Animal> animalList = new ArrayList<Animal>();
List<Mammal> mammalList = new ArrayList<Mammal>();
List<Dog> dogList = new ArrayList<Dog>();
new Test().test(animalList);
new Test().test(mammalList); // Error: The method test(List<? super Animal>) in the type Test is not applicable for the arguments (List<Mammal>)
new Test().test(dogList); // Error: The method test(List<? super Animal>) in the type Test is not applicable for the arguments (List<Dog>)
Dog dog = dogList.get(0);
}
}
Но тут возникает странная часть (по крайней мере, для меня).
Если мы объявим класс Test как универсальный, добавив только , то он COMPILES !и выдает java.lang.ClassCastException:
public class Test<T> {
...
}
,
Exception in thread "main" java.lang.ClassCastException: scjp.examples.generics.wildcards.Animal cannot be cast to scjp.examples.generics.wildcards.Dog
Мой вопрос заключается в том, почему добавление универсального типа класса (который нигде не используется) вызвало компиляцию класса иизменилось поведение подстановочных знаков?