我试着在一个例子中解释这个问题。我得到了一个名为X的接口,我得到了一个实现X的Y类。在List中收集了几个Y的实例。现在,我不明白这一点。 当我尝试将此列表分配给集合时,我收到编译器错误。 否则,当我将此列表分配给集合时,它可以正常工作。
List<Y> yList = new ArrayList<Y>();
// works
Collection<? extends X> coll1 = yList;
// error
Collection<X> coll2 = yList;
有人可以解释这两种变体之间的区别以及为什么第二种变体不起作用的原因。
答案 0 :(得分:1)
为此你需要更多地了解泛型的概念。
让我们看看以下代码:
List<Integer> ints = new ArrayList<Integer>();
ints.add(Integer.valueOf(1));
List<Number> numbers = ints;// This does not compile! and you will now see why:
numbers.add(new Double(2.3d));// This is valid
Integer i = ints.get(1); // This would be broken then because I expect an Integer but get a Double
这就是为什么你需要将你的List<X>
强制转换为Collection<? extends Y>
,这意味着该集合包含扩展Y的对象但你不知道确切的类型。你知道你可以转换为(Y),但你不知道集合中的实际类型是什么,因此不允许使用add()或addAll()等操作。