2010-11-15 49 views
1

我有以下幾點:獲取擴展ArrayList使用的類型的類名稱<T>?

public class Foo<T extends Grok> extends ArrayList<T> { 

} 

我怎樣才能找到被T在運行時所表示的類名?舉例來說,假設我分配是這樣的:

Foo<Apple> foo = new Foo<Apple>(); 

有沒有一種方法可以讓我得到蘋果作爲foo的構造函數?:

public Foo() { 
    super(); 

    String classname = this.getTypeClassName(); // "com.me.Apple" 
} 

我可以只添加一種方法使用的類名設定該類名,但寧願這樣用戶就不必做在內部把它拿來,

謝謝

回答

2

馬塞洛的回答解釋說,由於類型刪除,你不能像你想要的那樣做。不過,也有你想要什麼其他選擇這樣做,是這樣的:

public class Foo<T extends Grok> extends ArrayList<T> { 
    private Foo(Class<T> type) { 
    String classname = type.getName(); 
    ... 
    } 

    public static <T extends Grok> Foo<T> create(Class<T> type) { 
    return new Foo<T>(type); 
    } 

    ... 
} 

這使類的客戶只寫以下,這是大致相同的努力,作爲正常的構造,但向你的類型名稱太。

Foo<Apple> foo = Foo.create(Apple.class); 
+0

+1。是的,這是關於你可以做的最好的事情,告誡說絕對沒有辦法阻止'class Giraffe extends Grok {} ... Foo foo = Foo.create(Giraffe.class)''。 – 2010-11-15 22:51:31

+2

@Marcelo:不真實。 'Foo foo = Foo.create(Giraffe.class)'不會編譯。 'create'方法是通用的,並返回'Foo ',其中'T'是傳遞給它的''類型''。 'Foo.create(Giraffe.class)'返回'Foo ',而不是'Foo '。 – ColinD 2010-11-15 22:54:10

+0

我的錯誤。我沒有發現'Class '。我也不知道你甚至可以做到這一點! – 2010-11-16 02:11:32

4

由於類型擦除(在Java的泛型模型的缺陷之一)在一般情況下這是不可能的。如果foo傳遞了T的一個實例,它可以檢查該實例的類型,但不能保證它完全是T而不是派生類型。既然你試圖在構造函數中訪問這個類型,那麼它不可能持有這樣一個實例,所以你必須通過構造函數傳入一個蘋果。

+0

嗯,你的意思是如果T是「蘋果延伸水果」,我可能會得到水果。或者我可能會得到蘋果?就我而言,我只需要最遠派生的類。 – user291701 2010-11-15 22:43:13

+0

@ user291701:不完全。我的意思是,如果在你引用的例子中,你通過了foo一個RedApple,那麼你將回到「com.me.RedApple」而不是「com.me.Apple」,所以你不會真正知道foo的類型泛型參數,只是它所持有的東西。 – 2010-11-15 22:47:45