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



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

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的任何随机子类对象放入"动物"列表中,还是其他什么?

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

相反,List<Animal>可能包含CatDog实例,因此演员表是不合法的。

请参阅我的评论。

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

这是上限通配符的典型示例。请务必阅读 Java 教程。


如果你只想要一个包含你List<? extends Animal>所有元素的List<Animal>,你只能做......

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

这利用了这样一个事实,即ArrayList有一个需要Collection<? extends E>的构造函数。

因为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

最新更新