在我尝试编译的以下代码中:
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
的任何随机子类对象放入“动物”列表中,还是其他的?
答案 0 :(得分:3)
List<? extends Animal>
表示该列表包含Animal
未知子类型的所有实例,例如List<Cat>
,List<Dog>
等等。
List<Animal>
可能包含Cat
,Dog
个实例,因此投射不合法。
答案 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>
的事实。