我认为我对Java泛型有一些很好的理解。当类是泛型时Java通配符的奇怪行为
This code DOES NOT COMPILE我知道为什么。
我们可以通过测试方法只动物类型的列表或它的超类型(如对象的列表)
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);
}
}
但是这里来了奇怪的一部分(至少对我来说)。
如果我们只会增加<牛逼>声明类测试作为通用的,那么它编译!并抛出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
我的问题是,为什么将通用类型<牛逼>(未在任何地方使用)引起的类编译和改变通配符的行为?
+1。我应该补充一点,即使它在Eclipse中编译,它肯定会产生一系列可怕的警告,您应该注意这些警告。 – 2011-05-16 21:42:12
实际上不只是eclipse,该规范强制要求警告:“如果删除更改了方法或构造函数的任何参数的任何类型,则对原始类型的方法或构造函数的调用将生成未经检查的警告。通常,在运行时几乎所有可能导致*堆污染*的代码都需要在编译时生成未经检查的警告。 – meriton 2011-05-16 21:55:10