Java泛型 - 获取实际类型的泛型参数 [英] Java generics - obtaining actual type of generic parameter

查看:1342
本文介绍了Java泛型 - 获取实际类型的泛型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已阅读获取通用参数的类型在Java与反思后,它让我想知道这将是可能的。我使用了某人发布并使用该代码的解决方案。

  List< Integer> l = new ArrayList<>(); 
类actualTypeArguments =(Class)((ParameterizedType)l.getClass()。getGenericSuperclass())。getActualTypeArguments()[0];

然而,这对我不起作用,导致

  java.lang.ClassCastException:sun.reflect.generics.reflectiveObjects.TypeVariableImpl不能转换为java.lang.Class 

如果我删除了类转换,实际参数的类型是 E ,这是类型定义从List接口。



因此,我的问题是我在这里做错了什么?这种行为是我期望的,因为类型在编译期间应该被擦除,正确吗?

你使用的代码只适用于一些非常特殊的情况,其中实际的类型参数在编译时已知(并存储)。



例如,如果你这样做了: p>

  class IntegerList extends ArrayList< Integer> {} 

列表<整数> l = new IntegerList();

在这种情况下,您显示的代码实际上会返回 Integer.class <因为整数被烘焙到 IntegerList 中。code>

一些库(ab)通过使用类型标记来使用这个技巧。请参阅 GSON class TypeToken
$ b


表示泛型 T 。您可以使用此类来获取类的泛型类型。 >例如,要获取 Collection 的泛型类型,您可以使用:

  Type typeOfCollectionOfFoo = new TypeToken< Collection< Foo>>(){}。getType()


< blockquote>

这是可行的,因为在这里创建的匿名类已经编译了它的类型参数是 Collection< Foo>
$ b

请注意,这不起作用(即使 TypeToken 类不会阻止它的构造函数保存):

 类型t​​ypeOfCollectionOfFoo = new TypeToken< Collection< Foo>>()。getType()


I have read Get type of a generic parameter in Java with reflection post and it made me wonder how that would be possible. I used the solution that someone posted and using the code

List<Integer> l = new ArrayList<>();
Class actualTypeArguments = (Class) ((ParameterizedType) l.getClass().getGenericSuperclass()).getActualTypeArguments()[0];

This, however does not work for me, resulting in

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class

If I remove the class cast, the type of the actual argument is E, which is the type definition from List interface.

My question is, therefore, am I doing something wrong here? This behaviour is something I would have expected anyway, since the types are supposed to be erased during compile time, correct?

解决方案

The code you use only works in some very specific cases, where the actual type parameter is known (and stored) at compile time.

For example if you did this:

class IntegerList extends ArrayList<Integer> {}

List<Integer> l = new IntegerList();

In this case the code you showed would actually return Integer.class, because Integer is "baked into" the IntegerList.

Some libraries (ab)use this trick via the use of type tokens. See for example the GSON class TypeToken:

Represents a generic type T. You can use this class to get the generic type for a class. > For example, to get the generic type for Collection<Foo>, you can use:

Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>(){}.getType()

This works because the anonymous class created in here has compiled-in the information that its type parameter is Collection<Foo>.

Note that this would not work (even if the TypeToken class wouldn't prevent it by making its constructor protected):

Type typeOfCollectionOfFoo = new TypeToken<Collection<Foo>>().getType()

这篇关于Java泛型 - 获取实际类型的泛型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆