【问题标题】:Generics confusion泛型混淆
【发布时间】:2009-05-18 22:05:23
【问题描述】:

以下是来自 Kathy & Bert Bates SCJP 5 准备 CD 的问题。我也在其他地方发布了这个,但直到现在还没有得到令人满意的解释......请帮助我理解这一点:

public class BackLister {  
  //Insert code here
  {
    List<T> output=new LinkedList<T>();  
    for(T t:input)  
      output.add(0,t); 
    return output;  
  }  
}

以下哪项可以插入//Insert code here

  • 一个public static &lt;T&gt; List&lt;T&gt; backwards(List&lt;T&gt; input)
  • Bpublic static &lt;T&gt; List&lt;T&gt; backwards(List&lt;? extends T&gt; input)
  • Cpublic static &lt;T&gt; List&lt;T&gt; backwards(List&lt;? super T&gt; input)
  • Dpublic static &lt;T&gt; List&lt;? extends T&gt; backwards(List&lt;T&gt; input)
  • Epublic static &lt;T&gt; List&lt;? super T&gt; backwards(List&lt;T&gt; input)
  • Fpublic static &lt;? extends T&gt; List&lt;T&gt; backwards(List&lt;T&gt; input)

我了解 A 和 B 是正确的;但是,不是为什么 D 和 E 也是正确的。我可以看到 C 和 F 也不正确。谁能告诉我为什么 D 和 E 是正确的。

【问题讨论】:

  • 据我所知,所有的答案都是一样的。我错过了什么吗?
  • 看起来 SO 没有正确转义小于(或与号)字符。我认为缺少的部分是通用声明。
  • 您在其他地方发布了这个问题吗?不,你有一个完全相同的副本,stackoverflow.com/questions/858656/java-polymorphism-confusion
  • @MasterPeter:同一本书,不同的问题。
  • 是的,这是另一个问题 MasterPeter!

标签: java generics collections polymorphism


【解决方案1】:

答案 D,public static &lt;T&gt; List &lt;? extends T&gt; backwards(List &lt;T&gt; input),返回一个可以包含类型 T 或其任何子类的列表。因为它可以容纳T,所以它可以容纳输入中的任何元素,并且在这个意义上是“正确的”。

答案 E,public static &lt;T&gt; List &lt;? super T&gt; backwards(List &lt;T&gt; input),类似,但返回一个可以容纳 T 或任何超类的列表。由于它也可以容纳输入元素,所以它也是“正确的”。

选择这些备选方案之一将影响用户可能期望对结果列表执行的操作。

  • 使用List&lt;? extends T&gt; 输出,可以遍历列表并将每个元素分配给T 类型的变量,但没有任何元素,即使是T 类型,也可以安全地添加到@ 987654329@。 (有人可能将此列表称为List&lt;SubT&gt;,并在尝试将T 检索为SubT 时会得到ClassCastException。)

  • 使用List&lt;? super T&gt; 输出,如果元素的类型为T,则可以安全地将元素添加到List。但是,列表中的元素只能安全地分配给Object 类型的变量。 (有人可能会将此列表称为List&lt;Object&gt;,并添加ObjectT 的其他超类的实例。

  • 使用List&lt;T&gt;,可以安全地将列表的元素分配给T 类型的变量,并且可以将T 类型的元素添加到列表中(假设它是可修改的List实施)。

【讨论】:

  • 那么,List super T>,因为你只能将元素提取为对象?
  • 可以将 T 类型的项目添加到列表中。列表的“所有者”可能将其称为 List;它可以遍历元素并将它们作为 SuperT 访问,同时将列表公开为 List super T> to other,谁可以将元素添加到列表中。
【解决方案2】:

因为根据定义,List&lt;T&gt;List&lt;? extends T&gt;List&lt;? super T&gt;
? extends T 是表示 T 或子类型的通配符,? super T 是表示 T 的通配符或超类型。因此,返回 List&lt;T&gt; 将满足两种返回类型。

选择返回其中一个是有原因的,但这里的重点是它们是合法的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-11
    • 2016-09-28
    • 2011-04-25
    • 2012-03-05
    • 2017-07-01
    • 2015-05-13
    • 1970-01-01
    相关资源
    最近更新 更多