我正在使用泛型,我有一个我无法解决的代码。
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);
}
所以,它已经编译好了。 我理解为什么方法有效。但我可以理解为什么它被添加到具有严格泛型类型的主列表中。 感谢
答案 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都是对象列表。但这是一个非常糟糕的做法。