为了账号安全,请及时绑定邮箱和手机立即绑定

无法使用通配符泛型为Java集合添加值

无法使用通配符泛型为Java集合添加值

开满天机 2019-08-03 07:03:45
无法使用通配符泛型为Java集合添加值为什么此代码不编译(Parent是接口)?List<? extends Parent> list = ...Parent p = factory.get();   // returns concrete implementationlist.set(0, p);    // fails here: set(int, ? extends Parent) cannot be applied to (int, Parent)
查看完整描述

3 回答

?
守候你守候我

TA贡献1802条经验 获得超10个赞

它这样做是为了安全。想象一下,如果成功的话:

List<Child> childList = new ArrayList<Child>();childList.add(new Child());List<? extends Parent> parentList = childList;
parentList.set(0, new Parent());Child child = childList.get(0); // No! It's not a child! Type safety is broken...

意义List<? extends Parent>是“是某种类型的列表,它是Parent..我们不知道哪种类型-可能是List<Parent>..List<Child>,或List<GrandChild>.“这使取任何物品都是安全的。走出.的.List<T>API和转换自TParent,但打电话是不安全的在……里面List<T>API转换自ParentT..因为转换可能无效。




查看完整回答
反对 回复 2019-08-05
?
绝地无双

TA贡献1946条经验 获得超4个赞

List<? super Parent>

“生产者-延伸,消费者-超级”。你的List是…的消费者Parent物品。


查看完整回答
反对 回复 2019-08-05
?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

这是我的理解。

假设我们有一个泛型类型,有两个方法

type L<T>
    T get();
    void set(T);

假设我们有一个超级类型P,而且它有子类型C1, C2 ... Cn..(为了方便起见,我们说P是自身的一个子类型,实际上是Ci)

现在我们也有n混凝土类型L<C1>, L<C2> ... L<Cn>,就好像我们已经手动写了n类型:

type L_Ci_    Ci get();
    void set(Ci);

我们不需要手动写,这就是重点。确实有这些类型之间的关系

L<Ci> oi = ...;L<Cj> oj = oi; // doesn't compile. L<Ci> and L<Cj> are not compatible types.

对于C+模板来说,这就是故事的结尾。它基本上是宏扩展-基于一个“模板”类,它生成许多具体的类,它们之间没有类型关系。

对于Java来说,还有更多。我们也有一种L<? extends P>,它是任何一个超级类型的L<Ci>

L<Ci> oi = ...;L<? extends P> o = oi; // ok, assign subtype to supertype

什么样的方法应该存在于L<? extends P>?作为一个超级类型,它的任何方法都必须由它的子类型来预测。这种方法将起作用:

type L<? extends P>
    P get();

因为它的任何一个子类型L<Ci>,有一种方法Ci get(),它与P get()-重写方法具有相同的签名和协变返回类型。

这是行不通的set()不过-我们找不到X,所以void set(X)可以被void set(Ci)对任何Ci..因此set()方法不存在于L<? extends P>.

还有一个L<? super P>相反的方向。它有set(P),但不是get()..如果Si是一种超级类型的PL<? super P>是一种超级类型的L<Si>.

type L<? super P>
    void set(P);type L<Si>
    Si get();
    void set(Si);

set(Si)“重写”set(P)不是通常意义上的,但是编译器可以看到set(P)上的有效调用。set(Si)



查看完整回答
反对 回复 2019-08-05
  • 3 回答
  • 0 关注
  • 262 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信