如何在Java中将继承对象的列表转换为对象集合?
我有一个集合类型:
Collection<A> collecA
我的对象中有一个列表:
List<B> listB
其中 B 正在扩展 A
class B extends A { ... }
但我不能做以下事情:
collecA = listB
我不明白为什么因为集合是由List实现的。
我有一个集合类型:
Collection<A> collecA
我的对象中有一个列表:
List<B> listB
其中 B 正在扩展 A
class B extends A { ... }
但我不能做以下事情:
collecA = listB
我不明白为什么因为集合是由List实现的。
让我们假设一下,你可以做你所描述的:
class B extends A { ... }
Collection<A> collecA;
List<B> listB;
collecA = listB; // normally an error, but lets pretend its allowed
collecA.add(new A()); // PROBLEM!
方法调用看起来没问题,因为它是一个保存 s 的集合。但是,如果允许上述分配,那么我们就有问题了,因为实际上是对实例的引用 - 我刚刚将一个添加到只能容纳s的列表中!collecA.add(new A())
collecA
A
collecA
List<B>
A
B
阿斯克还说:
我不明白为什么因为集合是由List实现的。
集合是 List 的超类并不重要。即使您使用了两个列表,此分配也是非法的。
class B extends A { ... }
List<A> listA;
List<B> listB;
listA = listB; // still an error, still leads to the same problem
关键是 List<A>
变量只能引用
可以保存 A
s 的列表。但是,List<B>
实例不能保存 A
s。因此,不能为 List<A>
变量(如 listA
)分配对 listB 引用的 List<B>
实例的引用。
或者更一般地说:B
是A
的子类并不意味着SomeGenericClass<B>
是SomeGenericClass<A>
的子类(JLS §4.10:子类型不延伸到泛型类型:T <:U
并不意味着C<T> <:C<U>
。)
正是 Java 泛型教程中的这个例子/类比帮助我理解了这一点:
http://java.sun.com/docs/books/tutorial/java/generics/subtyping.html
“如果你想到有形的物体——你实际上可以想象的东西——比如笼子,理解为什么会变得容易得多:
// A cage is a collection of things, with bars to keep them in.
interface Cage<E> extends Collection<E>;
...
Cage<Lion> lionCage = ...;
Cage<Butterfly> butterflyCage = ...;
但是“动物笼子”呢?英语是模棱两可的,所以确切地说,让我们假设我们正在谈论一个“全动物笼子”:
Cage<Animal> animalCage = ...;
这是一个笼子,设计用于容纳各种动物,混合在一起。它必须有足够坚固的杆来容纳狮子,并且间隔足够紧密以容纳蝴蝶。
...
既然狮子是一种动物(狮子是动物的一个亚型),那么问题就变成了,“狮子笼子是一种动物笼子吗?是 的子类型吗?根据上述动物笼的定义,答案一定是“不”。这真是令人惊讶!但当你想到这一点时,这是完全有道理的:狮子笼不能被假定为蝴蝶,蝴蝶笼不能被假设为狮子。因此,两个笼子都不能被认为是“全动物”笼子:Cage<Lion>
Cage<Animal>
animalCage = lionCage; // compile-time error
animalCage = butterflyCage; // compile-time error
"
Collection<? extends A> collecA
这修复了它。问题不在于 ,而在于泛型类型。List extends Collection