获取泛型类的泛型参数的类型名称

ThR*_*R37 31 java generics

在使用泛型时我在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)


Jon*_*han 5

只要通过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获得.