數組是一個具體化類型。這意味着數組的確切類型在運行時是已知的。因此,在運行時,例如,String[]
和Integer[]
之間存在差異。
這不是泛型的情況。泛型是一個編譯時構造:它們用於在編譯時檢查類型,但在運行時確切類型不再可用。在運行時,類型參數只是Object
(或者如果類型參數具有上限,則爲上限)。所以在運行時,Collection<String>
和Collection<Integer>
的類型沒有區別。
現在,當您想創建一個類型參數的數組時,會出現問題。在運行時,不知道什麼是T
,所以如果你編寫new T[10]
,Java運行時不知道要創建什麼類型的數組,String[]
或Integer[]
。這就是爲什麼你不能以這種方式創建一個數組。
有幾個解決方法,其中沒有一個是完全令人滿意的。通常的解決方法是創建一個Object[]
,並把它轉換到你想要的類型的數組:
T[] theArray = (T[]) new Object[size];
但是,你要記住,這是非常不安全的。如果創建的箭頭的範圍很小,則只應該執行此操作,以便您可以手動確保該陣列僅包含T
實例,並且永遠不會將其分配給任何無法實現的實例。下面的代碼演示了此問題:
public class Foo<T extends Comparable> {
T[] createArray() {
return (T[])new Object[1];
}
public static void main(String... args) {
Foo<String> foo = new Foo<>();
String[] ss = foo.createArray(); // here
}
}
標有此行拋出一個異常,因爲你想投的Object[]
到String[]
!
如果你真的需要一個正確的運行時類型的數組,你需要使用反射。獲取某個類型的令牌,你需要的類型(類型Class<T>
的),並使用Array.newInstance(type, cize)
創建陣列,例如:
public T[] createArray(Class<T> type, int size) {
return (T[]) Array.newInstance(type, size);
}
簡單的答案是,你不能創建的項目類型從未來的數組一個類型參數。 – biziclop