0

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

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放入“动物”列表中,还是别的什么?

4

3 回答 3

3

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

List<Animal>相反,可能包含两个Cat,Dog实例,因此强制转换是不合法的。

于 2012-08-17T07:30:46.050 回答
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
于 2012-08-17T07:30:19.083 回答
1

我的评论

List<? extends Animal>意味着它是某个未知类型的列表,它AnimalAnimal. List<Animal>可以接受任何Animal,但List<Lion>(被安全地视为List<? extends Animal>)显然不能。

这是上界通配符的经典示例。确保您阅读了 Java 教程。


如果您只想 aList<Animal>包含您的所有元素List<? extends Animal>,您可以只做...

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

这利用了ArrayList具有构造函数的事实,该构造函数采用Collection<? extends E>.

于 2012-08-17T07:32:28.247 回答