【问题标题】:Java anonymous generic inheritanceJava 匿名泛型继承
【发布时间】:2013-11-23 22:44:52
【问题描述】:

看下一段代码:

ArrayList<? extends Object> list = new ArrayList<Object>();
list.add(new Object());

它不会编译。问题是为什么?

【问题讨论】:

    标签: java generics


    【解决方案1】:
    ArrayList<? extends Object>
    

    和刚才一样

    ArrayList<?>
    

    您可以将 any ArrayList 分配给这种类型的变量。例如,

    ArrayList<? extends Object> list = new ArrayList<String>();
    

    是合法的。显然,语言语义不允许您将Object 添加到这样的列表中。事实上,除了null 或您直接从列表中检索到的内容之外,他们不会让您添加任何内容

    正如 Lukas 在评论中所指出的,甚至将列表自己的项目添加回它也绝非易事:您需要一个辅助方法来将通配符捕获到命名类型中。

    public static void main(String[] args) {
      ArrayList<? extends Object> list = new ArrayList<String>();
      addOwn(list);
    }
    static <T> void addOwn(List<T> l) { l.add(l.get(0)); }
    

    【讨论】:

    • 或者你直接从列表中检索到的东西。:这让我很惊讶。你能举个例子吗? :-)
    • 来吧。你怎么知道? ;-)
    • 注意,这里有另一个“常用习语”来解决 Java 语言的愚蠢限制:stackoverflow.com/a/11982573/521799 ;-)
    • 我要注意的是,你永远不知道他们是否只是缺乏时间,或者在一些边缘情况下遇到了正式规范会遇到的问题。
    • 这就是我当时问的原因。不幸的是,在这些问题上很难得到权威的答案。很少有人记得 10 年前的相关邮件列表主题。在这种情况下,我猜,让这个“功能”正确并不会减轻它的重量。
    【解决方案2】:

    问题在于Foo extends Object 并不意味着Collection&lt;Foo&gt; 可以被视为Collection&lt;Object&gt; 的子类型。这仅仅是因为前者不允许你做后者所做的一切。例如,您不能将Object 添加到Collection&lt;Foo&gt;。使用泛型而不是一些具体的类 Foo 不会改变这一点。

    【讨论】:

      【解决方案3】:

      我认为原因是因为泛型类型不是多态的。当您将 wildcards ? 与 extends 一起使用时,除了 null 之外,您无法在集合中添加任何内容。

      下面是一个例子,如果允许的话会发生什么:

      Class Car{
      
      }
      class A extends Car {
      
      }
      class B extends Car{
      
      }
      

      现在你有List&lt;? extends Car&gt;

      public void someMethod(List<? extends Car> list){
      list.add(new A()); //this is not valid
      }
      

      你也可以像这样调用方法:

      List<B> someList = new Array:list<B>(); 
      somemethod(someList);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-06
        • 1970-01-01
        • 2021-10-11
        • 2011-04-25
        • 1970-01-01
        相关资源
        最近更新 更多