泛型类型问题

3
ArrayList<Integer> arrI = new ArrayList<Integer>();
ArrayList arrO = arrI; // Warning
/*  It is ok to add a String as it is an ArrayList of Objects
    but the JVM will know the real type, arrO is an arrayList of
    Integer... 
*/
arrO.add("Hello"); 
/*  How I can get a String in an ArrayList<Integer> ?? 
    Even if the compiler told me that I will get an Integer!
*/
System.out.println(arrI.get(0));

有人能解释一下这里正在发生什么吗?


你读并理解了警告吗?警告告诉你,通过编写此代码,你将绕过arrI的所有编译时类型检查。 - DJClayworth
@DJClayworth 好的,但是最后一行真的很奇怪。 - JohnJohnGa
3个回答

3
由于类型擦除的存在,泛型在运行时并不存在。实际上,这意味着您的ArrayList可以携带任何类型的对象。泛型只是一种方便程序员的工具,它可以让编译器验证部分代码的正确性。

3

由于泛型使用了类型擦除的实现方式,JVM并不知道真正的类型。

从字节码角度(也就是运行时行为)看,你的代码等效于:

ArrayList arrI = new ArrayList();
ArrayList arrO = arrI;
arrO.add("Hello"); 
System.out.println(arrI.get(0));

2

在运行时,泛型信息会丢失。它只能在编译时防止错误。

如果您尝试执行arr1.add("Hello"),它将在编译时引发错误,因为arr1已声明为ArrayList,但由于arr0可以在运行时的任何时刻分配给arr1 - 因此必须允许它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接