【问题标题】:Implementations and Collections实现和集合
【发布时间】:2011-08-17 19:35:19
【问题描述】:

为什么这不起作用...

public ArrayList<Edge> getEdges() {

return A;

//A is an Arraylist of type 'Action'. Action implements Edge.

}

接口Edge包括:public ArrayList getEdges();

尽管如此。

public Edge getEdges() {

return B;

//B is an 'Action'. Action implements Edge.

}

接口Edge包括:public Edge getEdges();

谢谢你, 切特

【问题讨论】:

    标签: java generics collections interface


    【解决方案1】:

    因为虽然EdgeAction 的子类型,但ArrayList&lt;Action&gt; 不是ArrayList&lt;Edge&gt; 的子类型。

    请改用ArrayList&lt;? extends Edge&gt;

    你可以看看this tutorial's 4. Wildcard section,虽然我建议你通读一遍,因为它真的很有帮助。

    【讨论】:

      【解决方案2】:

      这是因为ArrayList&lt;E&gt; 不是E 类型上的covariant。也就是说,您不能仅仅因为 Derived 继承自 Base 而用 ArrayList&lt;Derived&gt; 的实例替换 ArrayList&lt;Base&gt;

      考虑这种情况:String 继承自 Object然而,如果这意味着您可以将ArrayList&lt;String&gt; 用作ArrayList&lt;Object&gt;,则可以使用以下代码:

      ArrayList<Object> list = new ArrayList<String>();
      list.add(new Integer(5)); // Integer inherits from Object
      

      上述方法行不通,因为您无法将Integer 添加到ArrayList&lt;String&gt;。如果可以,那么这可能会发生:

      ArrayList<String> stringList = (ArrayList<String>)list;
      String string = stringList.get(0); // Not a string!
      

      作为Ziyao has indicated,实现这一点的正确方法是使用? extends Edge 语法。

      【讨论】:

        【解决方案3】:

        香蕉是一种水果。香蕉列表不是水果列表。

        否则,有人可以构建一个香蕉列表,将一个对水果列表的引用传递给您,然后您会(正确地)在其中插入一个苹果。香蕉列表的所有者会感到惊讶。

        【讨论】:

          【解决方案4】:

          因为泛型类型必须始终相同,而不是从它扩展的东西,你可以像这样重写它以使其工作:

          public ArrayList<? extends Edge> getEdges() {
          
          return A;
          
          //A is an Arraylist of type 'Action'. Action implements Edge.
          
          }
          

          【讨论】:

            猜你喜欢
            • 2012-08-27
            • 1970-01-01
            • 2021-09-14
            • 1970-01-01
            • 2013-11-12
            • 2015-05-14
            • 1970-01-01
            • 1970-01-01
            • 2019-02-21
            相关资源
            最近更新 更多