通用列表属性,获取泛型类型

时间:2011-10-06 20:47:29

标签: java list generics reflection generic-list

我的课程有List<String>List<SomeObject>

我得到了这个属性的类型:

propertyClass = PropertyUtils.getPropertyType(currentObject, property);

我想要做的是检查propertyClass是否为List<SomeType>并获取列表中类型的类对象。在此之后,我将要创建给定类型的ArrayList并用该类型的对象填充它(所有动态创建,我将使用它来动态加载文件中的一些数据)。

我可以使用反射来做到这一点吗?

3 个答案:

答案 0 :(得分:7)

编译后会删除泛型(由于type erasure)。所以你不能在运行时使用它们。

答案 1 :(得分:0)

我有类似的问题,我实际上找到了一个适合我的解决方案!

这可以做到,但可能不可靠(即它在所有情况下都不起作用)。 首先,您需要获得&#34; Field&#34; (通过反思)。然后得到&#34; GenericType&#34;。然后尝试将其转换为&#34; ParameterizedType&#34;。如果它实际上有参数,则可以这样做。 然后得到&#34; ActualTypeArguments&#34;。通常那些是&#34; Class&#34; es,所以你可以强制转换它们(如果不是你可以尝试Class.forName(...))然后你已经有了列表中元素的类型。

但是,如果我这样做,这不起作用:

class MyList extends List<String> {... }

然后是:

MyList list = new MyList(); // This would be List<String>

您实际上需要检查类型以查看它是否是List以及它是否具有在任何类或接口中声明的类型。但是可能存在多个类型,并且类型可以绑定到许多接口,而不仅仅是一个类。 当然你可以忽略那些不是&#34; List&#34;如果有的话,可能会抛出一个编译器错误(我可能会这样做)。

然后是通配符存在问题:列表列表= ... 您所能做的就是用&#34; Object&#34;替换它,但如果您想在列表中添加元素,则不安全! (再次,您可以在编译时检查它,如果有通配符则抛出错误)

另一种解决方案是使用已检查的List(请参阅Collections.checkedList(List,Class))并尝试在运行时获取该类型(您可能需要对此进行反射)。这样可以更好地工作,并且比泛型更强大。

答案 2 :(得分:0)

我找到了Bob Lee,Sven Mawson和Jesse Wilson的另一个答案:

  

[public class TypeToken:]表示泛型类型T. Java尚未提供方法   表示泛型类型,所以这个类的。迫使客户创建   此类的子类,用于检索类型信息   即使在运行时也是如此。

来源:http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/reflect/TypeToken.html

甚至有一个使用List<String>的例子,它确实有效。 TypeToken rawType java.util.ListtypeArguments设置为[java.lang.String]。这里没有类型擦除!但是它也不适用于List<? extends Foo>之类的通配符。

请注意,这与我在其他答案中解释的其他解决方案略有不同。在这里,您不分析java bean上的属性以获取类型信息。在这里,您实际上创建了一个存储类型信息的字段。我找不到任何公共构造函数或工厂方法来从您通过其他方式获得的类型信息创建TypeToken。所以我想它实际上只能用作一个空的匿名内部类。