2010-11-11 122 views
7

我有以下功能:獲取泛型類型的類型列表裏面的Java


    public <T> void putList(String key, List<T> lst){ 
      if (T instanceof String) { 
      // Do something  
      } 
      if (T instanceof Integer) { 
      // Do something 
      } 
    } 

在這個函數中,我想知道,如果<牛逼>是字符串或整數,所以我不知道是否有一種方法發現它的類型?我用上面的代碼,但它產生了錯誤

謝謝你提前。

+0

instanceof運算符不能在T.工作,你還是得從列表中得到一個元素,像善堂。 get(0)instanceof String – 2010-11-11 15:13:05

回答

8

隨着類型信息被刪除,您無法找到T的類型。檢查this瞭解更多詳情。但是如果列表不是空的,你可以從列表中獲得一個元素,並且可以找到使用instanceofif else

+4

假設你得到一個元素,它是空的,那麼instanceof不會幫你 – newacct 2010-11-11 19:00:04

-1

使用instanceof運算符。這就是說,泛型操作應該是通用的,所以要根據類型改變行爲。

+0

instanceof運算符不能用於泛型類型參數,如T – 2010-11-11 14:24:31

+0

您可以執行lst.get [0] instaceof String ... – PaulJWilliams 2010-11-11 14:29:42

+0

@Visage這是一個很好的觀點。@Teja Kantamneni在他的回答中也說過,只要列表不是空的 – 2010-11-11 14:33:19

9

由於erasure,在Java中不可能。大多數人所做的是添加一個類型令牌。示例:

public <T> void putList(String key, List<T> list, Class<T> listElementType) { 
} 

在某些情況下,可以在類型參數上獲得反射,但是在預先設置類型參數的情況下。例如:

public class MyList extends List<String> { 
    private List<String> myField; 
} 

在這兩種情況下,反射都可以確定List是String類型,但反射無法爲您的情況確定它。您必須使用類型令牌等不同的方法。

-1
Type genericType = lst.getType(); 

if(genericType instanceof ParameterizedType){ 
    ParameterizedType aType = (ParameterizedType) genericType; 
    Type[] fieldArgTypes = aType.getActualTypeArguments(); 
    for(Type fieldArgType : fieldArgTypes){ 
     Class fieldArgClass = (Class) fieldArgType; 
     System.out.println("fieldArgClass = " + fieldArgClass); 
    } 
} 
+0

嗨尼爾。感謝您的回答,但我找不到列表 – 2010-11-11 14:29:15

+0

的getType()方法這是因爲沒有這樣的事情。 – DJClayworth 2010-11-11 14:34:15

1

這是不可能的,以確定此由於erasure,這意味着該參數不存儲在代碼。然而,你可以通過一個額外的參數,指定什麼類型的列表是:

public <T> void putList(String key, List<T> lst, Class<T> listElementType) { 

}

,或者你可以在運行時確定每個元素的類型:

public <T> void putList(String key, List<T> lst){ 
    for (Object elem:lst) { 
     if (elem instanceof String) { 
     // Do something  
     } 
     if (elem instanceof Integer) { 
     // Do something 
     } 
    } 
} 
1

泛型被稱爲「擦除「,因爲它們僅在編譯時存在並被編譯器刪除。所以,沒有辦法確定通用類型的集合。對非空列表執行操作的唯一方法是獲取第一個元素並確定其類型。

這幾乎是DJClayworth提出的解決方案,但我認爲不需要檢查列表中的每個元素。如果您確定列表是使用泛型(new ArrayList()或new LinkedList()等)創建的,則其所有元素都保證是相同類型的。

0

如果你想運行對象的功能,你可以這樣做:

public <T> void putList(String key, List<T> lst){ 
for(T object : lst) 
{ 
    if(object instanceof String) { 
     doSomething(((String)object).doForString()) 
    } 
    if(object instanceof Integer) { 
     doSomething(((Integer)object).doForInteger()) 
    } 
}