通配符VS T - 获取并添加到列表

时间:2013-11-24 02:12:34

标签: java generics

考虑以下计划:

public class WCVsT {

    private void fooWC(List<? extends Number> l ) {
        l.add(l.get(0)); // 1 -  A Compile time error
    }

    private <T extends Number> void fooT(List<T> l) {
        l.add(l.get(0)); // 2 - No compile time error
    }
}

我有几个问题:

  1. 在1(在fooWC方法中)我正从列表中检索一个元素     将它添加回相同的列表 - 可能类型不安全?为什么呢     编译器不允许这样的操作?我可以理解编译器不允许将Cat添加到List<? extends Animal>,因为我可以将狗传给fooWC,但我的程序现在显示的应该始终是安全的。不是吗?
  2. 为什么使用fooT方法     类型参数而不是通配符允许这样的操作     fooWC - 通配符版本没有?
  3. 非常感谢任何帮助/提示。提前谢谢。

1 个答案:

答案 0 :(得分:4)

一个工作而另一个不工作的原因是两个方法都使用绑定<T extends Number>,在第二个方法(类型化方法)中,类型虽然未知,但相同整个方法中的类型 - 在调用期间,类型被锁定为特定(但未知)类型。

在第一种方法(无类型的方法)中,编译器只知道未知列表已经添加了未知类型,这可能是不同的未知类型。事实上,对于人类来说,它必须是相同的类型,因为目标和源是相同的对象,这对编译器是不可见的。

编译器认为第一个版本与:

在同一个桶中
List<Integer> list1;
List<Double> list2;
list1.add(list2.get(0);

它只知道类型受Number限制,但不一定是相同的类型。

第二个版本与:

在同一个桶中
List<Integer> list1;
List<Integer> list2;
list1.add(list2.get(0);

编译器不知道类型,但知道它是相同的类型。