2011-11-14 111 views
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)); 

任何人都可以解釋這裏發生了什麼?泛型類型問題

+0

您是否閱讀並理解警告?該警告告訴你,通過編寫這段代碼,你可以繞過arrI的所有編譯時類型檢查。 – DJClayworth

+0

@DJClayworth好的,但最後一行真的很奇怪 – JohnJohnGa

回答

3

JVM不知道真正的類型,因爲泛型是通過類型擦除實現的。

在字節碼(因此運行時行爲)的條款,您的代碼就相當於:

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

由於type erasure泛型在運行時不存在。在實踐中,這意味着您的數組列表可以攜帶任何類型的對象。泛型只是程序員的慣例,它讓編譯器驗證你的代碼的一些正確性。

2

在運行時,泛型信息丟失。它僅在編譯時防止錯誤。

如果您嘗試arr1.add(「Hello」);它會在編譯時拋出一個錯誤,因爲arr1已被聲明爲ArrayList,但是由於arr0可以在運行時的任何時刻分配arr1,所以必須允許它。