2012-08-30 48 views
2

我看過一些通用的限制通用和鑄造的Java規則

,當涉及到鑄造,它說什麼情況下,我們被允許投對象時,我們不能使用參數化類型

任何人都可以在解釋數據類型到它的子類,因爲泛型會在必要時自動執行強制轉換?

假設我有以下代碼:

T[] arrayVar =(T[]) new Object[1] //它會導致編譯器警告,但仍是好的

我爲什麼要使用CAST在這種情況呢?它不是說在通用中,投射將自動完成?

回答

1

假設T沒有被定義爲<T extends NotObject>,然後

T[] arrayVar =(T[]) new Object[1]// it causes a compiler warning but still okay 

交擦除是

Object[] arrayVar = (Object[]) new Object[1]; 

具有冗餘未經檢查的鑄件。

這不是類型安全的。

考慮當你做

f(arrayVar) 

其中

void f(Object[] out) { out[0] = "A string"; } 

如果在String不是T一個子類,可以發生,那麼你有一個類型安全違規會發生什麼。


爲了解決這個問題,你可以嘗試創建一個更具體類型的數組。 如果你能接受一個類型

Class<T> clazz 

隨後的參數,你可以創建你的陣列從而

T[] varArray = (T[]) Array.newInstance(clazz, 1); 

這是更類型安全的,因爲試圖在Number[]

out[0] = ""; 

例如在運行時將導致ArrayStoreException

這是不完全的(動態)類型安全的,因爲T可能會像List<String>一個類型,你仍然可以把List<Number>List[]沒有ArrayStoreException

+0

你能否更多地解釋我,在什麼情況下我應該使用劇組或者什麼時候不需要使用劇組? – Edi

+0

@Edi,在刪除之前,您需要進行強制轉換,創建的值不如通用接收器類型。在擦除後,這兩種類型是相同的,您需要使用其他機制來確保類型安全。您可以使用'@SuppressWarnings(「unchecked」)'註釋來告訴編譯器,您正在以某種方式保留類型安全性,但謹慎使用它。 –