【问题标题】:Compilation error caused by super wildcard超级通配符导致的编译错误
【发布时间】:2013-10-10 18:42:25
【问题描述】:

我对下面的代码有疑问。

你能告诉我为什么编译器拒绝接受 ty.add(new A()); 吗?毕竟 A 是 B 的超类(即,符合要求)。

错误信息如下:

C.java:15: error: no suitable method found for add(A)
                ty.add(new A());
                  ^
    method List.add(int,CAP#1) is not applicable
      (actual and formal argument lists differ in length)
    method List.add(CAP#1) is not applicable
      (actual argument A cannot be converted to CAP#1 by method invocation conversion)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object super: B from capture of ? super B
1 error

这里是代码(C.java):

import java.util.ArrayList;
import java.util.List;

class A
    {
    }
class B extends A
    {
    }
class C extends B
    {
    public static void main(String args[])
        {
        List<? super B> ty = new ArrayList<A>();
        ty.add(new A());
        ty.add(new B());
        ty.add(new C());
        }
    }

【问题讨论】:

    标签: java generics arraylist wildcard super


    【解决方案1】:

    您误解了? super B 的含义。这意味着它是一个在编译时未知的类,即BB 的超类。编译器只知道可以添加B对象,毕竟它可能是ArrayList&lt;B&gt;。所以它必须不允许添加A

    要允许添加A,请考虑将List&lt;? super A&gt;List&lt;A&gt; 作为ty 的类型。

    【讨论】:

    • 感谢您的回答。是的,在这种情况下我真的误解了 super。
    【解决方案2】:

    好吧,如果您只想添加子类对象,那么只需将您的列表声明为:

    List<A> list = new ArrayList<A>();
    list.add(new A());  // fine
    list.add(new B());  // fine
    

    原始列表声明的问题是,编译器不知道List&lt;? super B&gt; 引用的实际ArrayList 类型。例如,考虑List&lt;? super B&gt; 的所有类型的列表capture-convertible

    • List&lt;A&gt; => AB 的超类
    • List&lt;B&gt; => ? super B 可以捕获B
    • List&lt;Object&gt; => ObjectB 的超类

    因此,添加new A() 可能在第一个和第三个列表中有效,但对List&lt;B&gt; 无效。这就是为什么编译器不允许你添加new A()。但是,将列表声明为 List&lt;? super A&gt; 可以正常工作。但是,再次使用List&lt;A&gt;,这就是您想要的。

    创建像List&lt;? extends X&gt;List&lt;? super X&gt; 这样的列表的全部意义在于允许您将List&lt;E&gt; 的不同具体参数化实例化绑定到单个引用。


    参考资料:

    【讨论】:

      【解决方案3】:

      ?在这种情况下是一个存在量词,而不是一个全称。 List&lt; ? super B &gt; 应读作for some unknown T such that B &lt;: T, List&lt; T &gt;。这意味着您只能添加 B 实例,或者自相矛盾的是,添加 B 的任何子类,例如 C 实例。

      【讨论】:

      • 谢谢。确实,自相矛盾是一个非常合适的词。
      猜你喜欢
      • 1970-01-01
      • 2019-04-06
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 2013-02-01
      • 2015-09-12
      • 1970-01-01
      • 2021-05-17
      相关资源
      最近更新 更多