2011-01-27 91 views
10

如何使用反射實例化具有通用類的java.util.ArrayList?我正在編寫一個方法,在目標對象上設置java.util.List。目標對象和列表的通用類型在運行時已知:如何使用反射實例化具有通用類的java.util.ArrayList

public static void initializeList(Object targetObject, PropertyDescriptor prop, String gtype) { 
    try { 
     Class clazz = Class.forName("java.util.ArrayList<"+gtype+">"); 
     Object newInstance = clazz.newInstance(); 
     prop.getWriteMethod().invoke(targetObject, newInstance); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

回答

13

對象在執行時不知道其泛型類型。只需創建一個原始類型的新實例(java.util.ArrayList)。目標對象不會知道差異(因爲不是有任何區別)。

基本上Java泛型是一個編譯時的技巧,元數據在編譯的類中,但只是在執行時施放。有關更多信息,請參見Java generics FAQ

+0

只是爲了不創建重複的答案,使用反射就像做`new ArrayList ()`,因爲在運行時將「泛型類」解釋爲「Object」 – 2011-01-27 15:27:02

2

泛型只是編譯時的「詭計」。

反射僅爲運行時。

基本上,你不能 - 你只能創建一個「原始」ArrayList。如果您需要將它傳遞給採用通用參數的方法,則在構建後直接進行轉換將是安全的(不管「未選中」警告)。在這個例子中,由於使用了通用的Objects,所以沒有編譯時安全類型,所以不需要鑄造。

+0

泛型不僅僅是編譯時的事情。字段中的具體類型參數,方法和類定義實際上存在於字節碼中,並且可以在運行時通過反射來獲取。 – 2011-01-27 15:29:32

0

泛型僅在編譯時工作,因此如果您使用反射,它們將不可用。

查看更多關於此here

0

對象在執行時不知道其泛型類型。只需創建一個新的原始類型實例(java.util.ArrayList)。目標對象不知道差異(因爲沒有任何區別)。

0

泛型在很大程度上是編譯時功能。你所要做的是一樣的

public static void initializeList(Object targetObject, PropertyDescriptor prop, String gtype) { 
    prop.getWriteMethod().invoke(targetObject, new ArrayList()); 
} 

注:這可能會在Java 7中

6

與類型更改沒有必要做任何的反映了創建列表。只需傳入一些額外的類型信息(通常通過傳遞正確類型的類來完成)。

public static <T> List<T> createListOfType(Class<T> type) { 
    return new ArrayList<T>(); 
} 

現在你有需要的類型的列表,你可以大概/希望直接把它放在你的targetObject沒有任何反映。

+0

謝謝。它爲我工作 – 2017-04-07 18:26:19

相關問題