泛型混乱

时间:2009-05-18 22:05:23

标签: java generics collections polymorphism

以下是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可以插入以下哪些内容?

  • A 即可。 public static <T> List<T> backwards(List<T> input)
  • 即可。 public static <T> List<T> backwards(List<? extends T> input)
  • C 即可。 public static <T> List<T> backwards(List<? super T> input)
  • d 即可。 public static <T> List<? extends T> backwards(List<T> input)
  • 电子即可。 public static <T> List<? super T> backwards(List<T> input)
  • ˚F即可。 public static <? extends T> List<T> backwards(List<T> input)

我知道A和B是正确的;然而,不是为什么D和E也是对的。我可以看到C和F也是不正确的。有人可以告诉我为什么D和E是正确的。

2 个答案:

答案 0 :(得分:2)

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

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

选择其中一个替代方案将影响用户对结果列表的期望。

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

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

  • 使用List<T>,可以安全地将列表元素分配给T类型的变量,并可以将类型T的元素添加到列表中(假设它是一个可修改的List实现。

答案 1 :(得分:1)

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

有理由宁愿退回其中一个,但这里的要点是它们是合法的。