不兼容的类型:ArrayList <c <cap#1>&gt;无法转换为ArrayList <c <?>&gt;

时间:2017-12-19 15:20:06

标签: java generics compiler-errors

以下代码产生错误:

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 ?

它说类型不同但是如果我替换? for T in then它变成ArrayList<C<T>>与列表l的类型相同。

我的推理有什么问题?

1 个答案:

答案 0 :(得分:1)

只有当赋值的变量目标不允许在集合中添加元素时,编译器才接受为通用集合分配具有泛型子类型的集合。
这样可以保护泛型集合不会添加与集合子类型声明的类型不匹配的内容。

您的问题是以这种方式声明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