以下代码产生错误:
class A {
public static class C<T> {
public ArrayList<C<T>> lst;
}
public void main(String[] args) {
C<?> o = new C<>();
ArrayList<C<?>> l = o.lst;
}
}
错误信息:
a.java:10: error: incompatible types: ArrayList<C<CAP#1>> cannot be converted to ArrayList<C<?>>
ArrayList<C<?>> l = o.lst;
^
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
它说类型不同但是如果我替换?对于T然后它变成ArrayList<C<T>>
与列表l的类型相同。
我的推理出了什么问题?
仅当赋值的变量目标不允许在集合中添加元素时,编译器才接受为通用集合分配具有泛型子类型的集合。 这样可以保护泛型集合不会添加与集合子类型声明的类型不匹配的集合。
你的问题是通过这种方式声明l
:
ArrayList<C<?>> l
你可以添加任何C
实例:
l.add(new C<String>());
l.add(new C<Integer>());
通过将o.lst
分配给l
,您可以在o.lst
中添加任何内容,无论其声明的泛型。
所以编译器不接受这个赋值:
ArrayList<C<?>> l = o.lst;
如果你现在写:
ArrayList<?> l = o.lst;
这将是好的,因为l
不允许任何添加,但null
。