首先我們來看一個簡單的例子
Integer[] intArr = new Integer[1];
Object[] objArr = intArr;
objArr[0] = "xxx";
上面的這段代碼是可以正常編譯的张症,但在運行這段代碼的時候會報異常java.lang.ArrayStoreException
這是因為數(shù)組在創(chuàng)建的時候就確定了元素的類型驱犹,并且會記住該類型,每次向數(shù)組中添加值的時候霸株,都會做類型檢查,類型不匹配時就會拋異常java.lang.ArrayStoreException
知道了這個數(shù)組類型檢查機制后集乔,我們來看看創(chuàng)建泛型類的數(shù)組會有什么問題去件,首先我們創(chuàng)建一個泛型類:
public class A<T>{
private T value;
public A(T value) {
this.value = value;
}
// 省略 get 和 set 方法
// ...
}
我們嘗試來創(chuàng)建一個 A 類的數(shù)組:
A<String>[] arr = new A<String>[1]; // 編譯錯誤
上面的這行代碼根本不能通過編譯坡椒,也就是不允許我們創(chuàng)建泛型數(shù)組
為了解釋為什么不能創(chuàng)建泛型數(shù)組,這樣會帶來什么問題尤溜,我們假如上面的代碼可以通過編譯倔叼,接著看:
A<String>[] arr = new A<String>[1];
Object[] objArr = arr;
objArr[0] = new A<Integer>();
類似我們前面說的那樣,我們把 arr 賦給一個 Object[]宫莱,然后我們往數(shù)組中加入 A<Integer> 類型的值丈攒,這樣做是可以的,在編譯和運行期間都不會報錯授霸。因為泛型類型會被擦除巡验,A<String> 和 A<Integer> 的類型其實是一樣的:
System.out.println(new A<String>().getClass() == new A<Integer>().getClass());
// 輸出:true
這樣就逃過了數(shù)組的類型檢查機制,在我們使用中就會造成類型轉換錯誤碘耳。
所以显设,Java 中不允許創(chuàng)建泛型的數(shù)組。
注意
有一種繞過“不能創(chuàng)建泛型數(shù)組”限制的方法辛辨,就是使用強制類型裝換:
A<String>[] arr = (A<String>[]) new A[1];
當然捕捂,這么做是不安全的,當我們向數(shù)組中放入一個 A<Integer>斗搞,然后以 String 類型取出時會報異常java.lang.ClassCastException
指攒,如下代碼所示:
A<String>[] arr = (A<String>[]) new A[1];
Object[] objArr = arr;
objArr[0] = new A<Integer>(1);
A<String> a = arr[0];
String s = a.getValue();
// java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String