获取generics类的通用参数的类型名称

在使用generics时我在java中遇到一个小问题。 我有一个A类:

 public class A 

A的方法中,我需要获取T的类型名称。 有没有办法用T找到字符串?

(如果我创建A temp = new A();我希望能够在某一点获得java.lang.String – 我必须使用generics,因为我的一个方法必须返回一个List )。

这似乎很容易,但我不知道该怎么做。

由于类型擦除 ,通常无法执行此操作 – A的实例不知道 T的类型。 如果需要,一种方法是使用类型文字:

 public class A { private final Class clazz; public A(Class clazz) { this.clazz = clazz; } // Use clazz in here } 

然后:

 A x = new A(String.class); 

这很难看,但那是什么类型的擦除:(

另一种方法是使用类似Guice的TypeLiteral 。 这是有效的,因为用于指定超类的类型参数不会被删除。 所以你可以这样做:

 A a = new A() {}; 

a now指的是A子类 ,因此通过获取a.getClass().getSuperClass()您最终可以返回String 。 但这太可怕了。

您可以从子类中获取generics的名称。 看这个例子。 我们定义一个这样的父类:

 public class GetTypeParent { protected String getGenericName() { return ((Class) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]).getTypeName(); } } 

然后我们以这种方式定义它的子类:

 public class GetTypeChild extends GetTypeParent { public static void main(String[] args) { GetTypeChild getTypeChild = new GetTypeChild(); System.out.println(getTypeChild.getGenericName()); } } 

您可以在main方法或任何实例方法中看到,我能够获取generics类型的名称,在这种情况下,main将打印: java.lang.Integer

简短回答:不可能。

稍微长一点的答案:编译代码后,类型参数将被丢弃。 因此,Java无法知道您在那里设置了什么。 但是,您可以将有问题的类传递给您的对象并对其进行操作:

 public class A { private final clazz; A(Class clazz){ this.clazz = clazz; } ... } 

只要通过A的子类指定type参数,这当然是可能的:

 public class B extends A {} Class typeArg = TypeResolver.resolveRawArgument(A.class, B.class); assert typeArg == String.class; 

TypeResolver可通过TypeTools获得 。

Java中的generics是通过擦除实现的,所以不,你将无法获得在运行时用于创建generics集合的“类型”的名称。 另外,为什么不检查元素以了解它属于哪种类型?

如果你在一个子类中进行它,它的父类定义generics类型,这对我有用:

 // get generic type class name String name = ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0].toString(); // then when you've got the name, you can make the Class object Class.forName(name.replace("class ", "")) 

我无法在第一个#toString()使用#getClass()而不是#toString()的原因是我总是得到“Class”类,这对我来说没用。

通常情况下,Apache有一个使用TypeUtils的解决方案:

https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/reflect/TypeUtils.html

以上问题的一个简单示例:

 TypeUtils.getTypeArguments(temp.getClass(), A.class).get(A.class.getTypeParameters()[0]) 

免责声明:我没有尝试首先构建它,但过去曾以类似的方式使用此实用程序。