2016-05-13 56 views
1

我有以下代碼:如何初始化包含泛型的泛型數組?

public class I<T> { 
    private T t; 
    public I(T t) { 
     this.t=t; 
    } 
} 

public class G<T> { 
    private I<T> tab[]; 
    public G() { 
     tab=(I<T>[]) new Object[10]; 
    } 
} 

調用G()拋出一個ClassCastException。

我該如何編寫G構造函數才能初始化選項卡?

回答

1
tab=(I<T>[]) new I<?>[10]; 

是答案,但它對我來說依然神祕!

0

爲了讓你自己的回答有點神祕:請注意,Java通過擦除來實現泛型,即編譯器基本上會執行一些編譯時檢查,然後丟棄泛型。

所以,從運行時間來看,你的第一種方法可以歸結爲:

I[] tab = (I[]) new Object[10]; 

由於數組類型是真正傑出的課程,你會得到一個類轉換異常在這裏,因爲我[]類。與Object []。類不一樣。

你的第二個方法是(丟棄仿製藥):

I[] tab = (I[]) new I[10]; 

...這裏沒有問題。

+0

你可以提供一個鏈接,瞭解這個人 – emotionlessbananas

+0

檢查教程線索在https://docs.oracle.com/javase/tutorial/java/generics/erasure.html – mtj

+0

感謝鏈接 – emotionlessbananas

0

Tab是我。我的數組是一個對象,而是通過new Object()創建了一個簡單的對象是一個一,這解釋了爲什麼第一種方式產生的錯誤。您必須創建一個數組來初始化tab

但這並非全部:java泛型使用類型擦除。那意味着在運行時編譯器不知道T是什麼。當T不再有任何意義時,運行時執行tab = new I<T>[10];,因此是錯誤。

的解決方案是創建的任何(​​)我的陣列或I<Object>陣列或者甚至使用舊的(預通用)語法new I[10]

這裏沒有提到,但是當你真的需要知道泛型中參數的類型時,常見的習慣用法是在構造函數或setter中明確傳遞類,以便泛型對象可以使用它。代碼可以是:

class G<T> { 
    private I<T> tab[]; 
    private Class<T> clazz; 
    ... 
    public G(Class<T> clazz) { 
     this.clazz = clazz; 
     tab = new I[10]; 
     // here we can use the type of T from clazz by reflexion... 
    } 
}