2011-01-27 180 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

相关问题