2012-08-06 23 views
2

我在網上看到它在一些地方提到過,在某些情況下,可以使用反射API來獲取有關通用數據類型的信息,這些數據類型我認爲會通過類型擦除而丟失。在Java中輸入擦除的例外是什麼?

我在尋找類型刪除未完成的情況的完整列表,即仍然可以通過反射訪問某些東西。一個很好的例子列表和相關的反射代碼可以在泛型上得到很好的表現。

UPDATEhttp://tutorials.jenkov.com/java-reflection/generics.html恰好就是我要找的例子。

+0

如果您投票結束此問題,請發表評論並告訴我爲什麼? – ams 2012-08-06 05:25:17

+0

鏈接到這些地方會有所幫助。 – Thilo 2012-08-06 05:29:24

+0

@Thilo http://stackoverflow.com/questions/4713438/type-erasure-in-java是一個地方的例子,提到並不是所有的類型信息都會丟失。 – ams 2012-08-06 05:41:25

回答

6

我認爲它只是歸結到這一點:

  • 沒有對象實例存儲任何類型的信息。

  • 的類,但保留其所有的通用簽名(否則你不會有任何泛型類型在編譯時檢查)

因此,使用反射,你可以看到一個泛型類型信息給定班級。

例子:

class MyList extends ArrayList<MyObject>{} 

List<MyObject> x = new MyList(); 

反射會告訴你,這是myObject的列表(因爲這些信息被編譯成MYLIST類)。

List<MyObject> x = new ArrayList<MyObject>(); 

反射不會告訴你任何有用的東西(因爲ArrayList的一無所知的MyObject)。

+1

+1保留所有通用信息的原因是'javac'編譯器能夠完成它的工作。例如您必須能夠使用已正確編譯的代碼中的泛型編譯代碼。 – 2012-08-06 07:50:47

+0

除了超類之外,非專用字段類型中的泛型以及方法參數和返回類型也都在那裏,用於類型檢查。 – newacct 2012-08-06 09:14:51

+0

是的,所有這些都是類定義的一部分。上面的例子並不意味着詳盡無遺。但請注意,在所有這些情況下,泛型都可用於字段/參數/返回類型*定義*(簽名),而不是分配給它們的任何對象的實際運行時值.. – Thilo 2012-08-06 09:57:46

2

一般的想法是,如果您創建一個具有特定類型的泛型類型的子類的命名或匿名類,那麼該子類不是泛型的,並且不會進行類型擦除。假設您可以獲得子類的Class對象,則可以對該對象使用反射來查明參數類型是什麼。

當你考慮它時,這不是擦除規則的一個「例外」。相反,它通過明確地表達它來安排所討論的類不是通用的。

+0

「以找出什麼參數類型是「否,您正在查找它所擴展的超類的類型參數。 – newacct 2012-08-06 09:16:08