【问题标题】:Generic List property, get type of generic泛型列表属性,获取泛型类型
【发布时间】:2011-10-06 20:47:28
【问题描述】:

我有一个类具有 List<String>List<SomeObject> 的属性。

我得到的属性类型是这样的:

propertyClass = PropertyUtils.getPropertyType(currentObject, property);

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

有没有办法使用反射来做到这一点?

【问题讨论】:

  • List 最初是如何创建的?

标签: java list generics reflection generic-list


【解决方案1】:

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

【讨论】:

  • 我决定使用数组而不是列表并让它像那样正常工作:)
【解决方案2】:

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

这可以做到,但它可能不可靠(即它并非在所有情况下都有效)。 首先,您需要获得“场”(通过反射)。然后获取“GenericType”。然后尝试将其转换为“ParameterizedType”。如果它实际上有一个参数,这是可能的。 然后得到“ActualTypeArguments”。通常这些是“类”,因此您可以强制转换它们(如果不是,您可以尝试 Class.forName(...)),然后您已经拥有列表中元素的类型。

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

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

然后:

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

您实际上需要检查类型以查看它是否是 List 以及它是否具有在任何类或接口中声明的类型。但是可能不止一个,并且类型可以绑定到许多接口,而不仅仅是一个类。 当然,您可以忽略不是“列表”的属性,如果有的话,可能会引发编译器错误(我可能会这样做)。

然后就是通配符的问题:List list = ... 您所能做的就是用“对象”替换它,但是如果您想将元素添加到列表中,那是不安全的! (同样,你可以在编译时检查,如果有通配符则抛出错误)

另一个解决方案是使用检查列表(请参阅 Collections.checkedList(List, Class))并尝试在运行时获取该类型(您可能需要对此进行反射)。这将比泛型更好,并且更健壮。

【讨论】:

    【解决方案3】:

    我找到了 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&lt;String&gt; 的示例,它确实有效。 TypeToken 将有一个 rawTypejava.util.ListtypeArguments 设置为 [java.lang.String]。这里没有类型擦除!但是,它也不适用于List&lt;? extends Foo&gt; 等通配符。

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

    【讨论】:

      猜你喜欢
      • 2020-01-29
      • 2015-02-15
      • 2012-12-17
      • 1970-01-01
      • 2018-02-16
      • 2015-07-28
      • 2011-10-08
      • 2015-12-12
      • 1970-01-01
      相关资源
      最近更新 更多