2011-09-08 63 views
5

你好,我有一個方法,應根據類型返回不同的結果。檢查泛型的實例嗎?

我可以這樣做來檢查泛型類型。

public <T> T search(final String query){ 
T returnValue = null; 
if (returnValue instanceof String){ } 
if (returnValue instanceof Integer){ } 
if (returnValue instanceof MyObject){ } 

但爲什麼我不能這樣做?

public <T> T search(final String query){ 
T returnValue = null; 
if (T instanceof String){ } 
if (T instanceof Integer){ } 
if (T instanceof MyObject){ } 

調用代碼。

String id = myObjcet.<String> search("select ..."); 

回答

4

Java實現泛型「通過擦除」。這意味着在運行時根本沒有泛型知識。相反,編譯器會檢查泛型,但在封面下它會將所有內容都轉換爲Object(或最近的泛型邊界)。

如果您在使用javap的反編譯這個方法,你會看到它的內容:

public Object search(... 

至T的每個引用被移除。

這是反映也經常在JRE類與樣結構在Java中,仿製藥的一個嚴重的限制:

SomeClass<String> x = new SomeClass<String>(String.class); 

哪裏是必要的,因爲構造函數的字符串(String.class)的第三次重複需要知道它在哪個類上運行。

這種範例儘管可怕,但可以解決您的問題。

有關泛型的信息實際上包含在.class文件中,作爲元數據,它們可以使用反射進行檢查,並且在某種程度上也可以解析。但是,在你的情況下這是不可能的,但例如在列表獲取器上由ORM使用。例如,使用Hibernate,像這樣的一個getter:

public List<Group> getGroups() { 

可以通過休眠,使其知道列表應該持有集團的情況下,相應地調整它的查詢進行檢查。 (但是,即使泛型沒有以這種方式實現,T不是實例,它是一個類,寫String的instanceof String也是錯的。它應該是if(T.equals(String.class)))

+0

非常感謝這個精彩的解釋,我會盡快答覆你,讓我儘快回答。 – Farmor

1

因爲T在運行時被擦除。它只在編譯時纔有。 returnValue是變量 - 它在運行時出現。

1
public <T> T search(Class<T> clazz, String query){ 
T returnValue = null; 
if (clazz==String.class){ } 
if (clazz==Integer.class){ } 
if (MyObject.clazz.isAssignableFrom(clazz){ } 


String id = myObjcet.search(String.class, "select ...");