在使用泛型时我在java中遇到一个小问题.我有一节课A:
public class A<T>
Run Code Online (Sandbox Code Playgroud)
在一个方法中A,我需要获取类型名称T.有没有办法找到s使用的字符串T?
(如果我创建A<String> temp = new A<String>();,我希望能够获得java.lang.String一点 - 我必须使用通用性,因为我的一个方法必须返回一个List<T>).
这似乎很容易,但我不知道该怎么做.
Jon*_*eet 45
由于类型擦除通常不能这样做- 一个A<String>不知道类型的实例T.如果需要,一种方法是使用类型文字:
public class A<T>
{
private final Class<T> clazz;
public A<T>(Class<T> clazz)
{
this.clazz = clazz;
}
// Use clazz in here
}
Run Code Online (Sandbox Code Playgroud)
然后:
A<String> x = new A<String>(String.class);
Run Code Online (Sandbox Code Playgroud)
这很难看,但那是什么类型的擦除:(
另一种方法是使用像Guice这样的东西TypeLiteral.这是有效的,因为用于指定超类的类型参数不会被删除.所以你可以这样做:
A<String> a = new A<String>() {};
Run Code Online (Sandbox Code Playgroud)
a现指子类的A<String>,所以通过让a.getClass().getSuperClass()你能最终回到String.但这太可怕了.
Enr*_*rin 24
您可以从子类中获取泛型的名称.看这个例子.我们定义一个像这样的父类:
public class GetTypeParent<T> {
protected String getGenericName()
{
return ((Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0]).getTypeName();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们以这种方式定义它的子类:
public class GetTypeChild extends GetTypeParent<Integer> {
public static void main(String[] args) {
GetTypeChild getTypeChild = new GetTypeChild();
System.out.println(getTypeChild.getGenericName());
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在main方法或任何实例方法中看到,我能够获取泛型类型的名称,在这种情况下,main将打印:java.lang.Integer.
Urs*_*pke 10
简短回答:不可能.
稍微长一点的答案:编译代码后,类型参数将被丢弃.因此,Java无法知道你在那里设置了什么.但是,您可以将有问题的类传递给您的对象并对其进行操作:
public class A<T> {
private final Class<T> clazz;
A(Class<T> clazz){
this.clazz = clazz;
}
...
}
Run Code Online (Sandbox Code Playgroud)
只要通过A的子类指定type参数,这当然是可能的:
public class B extends A<String> {}
Class<?> typeArg = TypeResolver.resolveRawArgument(A.class, B.class);
assert typeArg == String.class;
Run Code Online (Sandbox Code Playgroud)
TypeResolver可通过TypeTools获得.