关于java反射获取泛型

时间:2023-03-09 01:24:23
关于java反射获取泛型
public class Test<T> {
private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {};
private final Type type = typeToken.getRawType(); public void foo() {
System.out.println(this.type);
} public static void main(String[] args) {
Test<Integer> test = new Test<Integer>() {};
Test<Integer> test2 = new Test<Integer>();
test.foo();// class java.lang.Integer
test2.foo();//
}
}

利用以上代码可以获取泛型类型,对于test与test2的输出不同有些困惑。以下为解答:

首先,当利用

Test<String> test2 = new Test<String>();

进行实例化的时候,java没有办法将String传过去。于是

private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {};

就无法得知T的具体类型,因此只能输出T。

接着对于

  private final TypeToken<T> typeToken = new TypeToken<T>(getClass()) {};

根据javadoc(见参考链接2)

Constructs a new type token of T while resolving free type variables in the context of declaringClass.

Clients create an empty anonymous subclass. Doing so embeds the type parameter in the anonymous class's type hierarchy so we can reconstitute it at runtime despite erasure.

只有创建匿名子类,才能将类型参数嵌入到匿名子类的结构中,此时就能获取到Integer了(关于匿名子类如何操作,见参考链接3)

参考1:https://*.com/questions/38046880/how-to-use-typetoken-to-get-type-parameter

参考2:https://google.github.io/guava/releases/snapshot/api/docs/com/google/common/reflect/TypeToken.html#TypeToken(java.lang.Class)

参考3:http://gafter.blogspot.com/2006/12/super-type-tokens.html