在我尝试编译的以下代码中:
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>
可能包含Cat
,Dog
实例,因此演员表是不合法的。
请参阅我的评论。
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