Java:泛型,超类型引用指向<! - ?扩展超类 - >类型引用

时间:2012-08-17 07:27:15

标签: java generics

在我尝试编译的以下代码中:

List<Animal> animals;
List<? extends Animal> some;
animals = some;

我收到以下错误:

Type mismatch: cannot convert from List<capture#2-of ? extends Animal> to List<Animal>

但是包含<? extends Animal>的列表保证其中至少包含Animal类型,那么为什么会出现此错误?这是因为如果允许的话,我可以将Animal的任何随机子类对象放入“动物”列表中,还是其他的?

3 个答案:

答案 0 :(得分:3)

List<? extends Animal>表示该列表包含Animal未知子类型的所有实例,例如List<Cat>List<Dog>等等。

List<Animal>可能包含CatDog个实例,因此投射不合法。

答案 1 :(得分:1)

因为List<? extends Animal>不是List<Animal>的子类型。如果您的作业合法,则可以将Dog对象添加到Cat列表中。像这样:

List<Animal> cats = new List<Animal>();
cats.add(new Cat());
List<Dog> dogs = cats; //if was legal
dogs.add(new Dog)); //now you have a dog in a list of cats

小心阵列!对于数组,赋值是合法的,并且在编译时但在运行时不会捕获问题。例如:

Animal[] cats = new Animal[] {...};
Dogs[] dogs = cats; // OK at compile time

答案 2 :(得分:1)

请参阅my comment

List<? extends Animal>表示它是某个未知类型的列表,可以是Animal,也可以是Animal的子类。 List<Animal>可以接受任何Animal,但List<Lion>(安全地被视为List<? extends Animal>)显然不能接受。{/ p>

这是upper-bounded wildcards的典型示例。请务必阅读Java Tutorial。


如果您只想要List<Animal>包含List<? extends Animal>的所有元素,则只能执行...

final List<? extends Animal> someAnimals = ...;
final List<Animal> animals = new ArrayList<Animal>(someAnimals);

这利用了ArrayList有一个constructor Collection<? extends E>的事实。