泛型列表属性,获取泛型的类型

发布于 2024-12-08 11:13:51 字数 401 浏览 4 评论 0原文

我有一个具有属性 ListList 的类。

我得到的属性类型如下:

propertyClass = PropertyUtils.getPropertyType(currentObject, property);

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

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

I have a class that has a propery List<String> or List<SomeObject>.

I get the type of the property as this:

propertyClass = PropertyUtils.getPropertyType(currentObject, property);

What I want to do is check that the propertyClass is a List<SomeType> and get the class object for the type in the list. After this I will want to create an ArrayList of the given type and fill it with object of that type (all created dynamically, I will use this to dynamically load some data from a file).

Is there I way I can do this using reflection?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

可是我不能没有你 2024-12-15 11:13:51

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

Generics are erased after compilation (due to type erasure). So you can't use them at runtime.

幽梦紫曦~ 2024-12-15 11:13:51

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

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

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

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

然后:

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

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

然后就是通配符的问题:List list = ...
您所能做的就是将其替换为“Object”,但如果您想将元素添加到列表中,这并不安全! (同样,您可以在编译时进行检查,如果存在通配符则抛出错误)

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

I have a similar problem and I actually found a solution that works for me!

This can be done but it might be unreliable (i.e. it doesn't work in all situations).
First you need to get the "Field" (via reflections). Then get the "GenericType". Then try to cast this to "ParameterizedType". This is possible if it actually has a parameter.
Then get "ActualTypeArguments". Usually those are "Class"es, so you can cast them (if not you could try Class.forName(...)) and then you already have the type of the elements in the list.

However, this doesnt work if I do this:

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

And then later:

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

You'd actually need to inspect the type to see if it is a List and if it has a type declared in any class or interface. But there could be more than one and the type could be bound to many interfaces, not just one class.
of course you could just ignore properties that aren't "List" and maybe throw a compiler error if there is one (I'll probably do just that).

Then there is the problem with wildcards: List list = ...
All you can do is substitute it with "Object", but that isn't safe if you want to add elements to the list! (again, you could check that at compile time and throw an error if there are wildcards)

Another solution is to use a checked List (see Collections.checkedList(List, Class)) and try to get that type at runtime (you probably need reflection for that). This would work much better and would be much more robust than just generics.

腻橙味 2024-12-15 11:13:51

我找到了 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 它确实有效。 TypeToken 将具有 rawTypejava.util.List,并且 typeArguments 设置为 [java .lang.String]。这里没有类型擦除!但是,它也不适用于通配符,例如 List

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

I have found another answer by Bob Lee, Sven Mawson, and Jesse Wilson:

[public class TypeToken:] Represents a generic type T. Java doesn't yet provide a way to
represent generic types, so this class does. Forces clients to create
a subclass of this class which enables retrieval the type information
even at runtime.

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

There even is an example using List<String> and it really works. The TypeToken will have a rawType of java.util.List and typeArguments is set to [java.lang.String]. There is no type erasure here! However it does also not work for wildcards such as List<? extends Foo>.

Note that this is a bit different from the other solution I explained in my other answer. Here you don't analyze a property on a java bean to get the type information. Here you actually create a field that stores the type information. I can't find any public constructor or factory method to create a TypeToken from type information that you got some other way. So I guess it really can only be used as an empty anonymous inner class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文