java通用数组列表

时间:2013-12-09 22:43:13

标签: java generics methods

我正在使用泛型,我有一个我无法解决的代码。

public static void main(String[] args) {
    ArrayList<Integer> list=new ArrayList<Integer>();
    list.add(1);

    System.out.println(list);
    t(list);
    System.out.println(list);
}

static void t(List list){
    list.add("test2");
    list.add(3);
}

所以,它已经编译好了。 我理解为什么方法有效。但我可以理解为什么它被添加到具有严格泛型类型的主列表中。 感谢

3 个答案:

答案 0 :(得分:3)

这是在Java中使用原始类型的问题。实际上,编译器应该警告您add方法中对t的未经检查的调用。这种警告意味着“类型安全”无法保证,正如您所示,它无法保证。

它编译for backwards compatibility reasons,并且由于type erasure而运行,这意味着在运行时ArrayList只保留Object

请注意,如果您尝试使用

提取与ClassCastException对应的元素,则可能会导致运行时String
Integer oops = list.get(1);  // Cannot cast from `String` to `Integer`

答案 1 :(得分:2)

因为类型擦除。在运行时,泛型被删除,因此当您将列表传递给静态方法时,它不会失败,因为它假定列表为Objects

  

泛型被引入Java语言以提供更紧密的类型   在编译时检查并支持通用编程。至   实现泛型,Java编译器将类型擦除应用于:

     
      
  • 如果类型参数是无界的,则将泛型类型中的所有类型参数替换为其边界或对象。生成的字节码,   因此,只包含普通的类,接口和方法。
  •   
  • 如有必要,请插入类型转换以保护类型安全。
  •   
  • 生成桥接方法以保留扩展泛型类型中的多态性。
  •   

有关类型擦除的更多信息:http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

答案 2 :(得分:0)

方法“t”作为参数类型原始列表(不是整数列表)。所以你可以放任何你想要的东西,因为默认情况下每个List都是对象列表。但这是一个非常糟糕的做法。