通过反射获取泛型
磊磊

这是怎么做到的?反射不是运行时吗?运行时不是没有泛型吗?

网上看了一大堆

发现虽然泛型是被擦除了,存储的还是Object。

但是当类(Class)作为某个对象的时候,成员变量、方法返回值等位置的具体泛型类型的时候,Javac 会编译进class字节码。

JVM加载字节码的时候,JVM将解析到字节码的泛型信息保存下来的,所以反射可以获取。

通过反射获取泛型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class Demo {
Map<Character, Integer> field;
public void demoMethod(Map<Character, Integer> args) {}

public static void main(String[] args) throws Exception {
// 根据子类获取父类泛型
Map<String, Integer> map = new HashMap<String, Integer>() {};
Type superClass = map.getClass().getGenericSuperclass();
if (superClass instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) superClass;
Type[] typeArgs = pt.getActualTypeArguments();
System.out.println("变量第一个泛型为:" + typeArgs[0].getTypeName());
System.out.println("变量第二个泛型为:" + typeArgs[1].getTypeName());
}

// 成员变量泛型获取
Field field = Demo.class.getDeclaredField("field");
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType pt = (ParameterizedType) genericType;
Type[] typeArgs = pt.getActualTypeArguments();
System.out.println("成员变量第1个,泛型为:"+typeArgs[0].getTypeName());
System.out.println("成员变量第2个,泛型为:"+typeArgs[1].getTypeName());
}

// 方法参数泛型
Method method = Demo.class.getMethod("demoMethod",Map.class);
Type[] genericTypes = method.getGenericParameterTypes();
Type oneParam = genericTypes[0];
ParameterizedType pt = (ParameterizedType) oneParam;
Type[] typeArgs = pt.getActualTypeArguments();
System.out.println("方法第1个,泛型为:"+typeArgs[0].getTypeName());
System.out.println("方法第2个,泛型为:"+typeArgs[1].getTypeName());
}
}
由 Hexo 驱动 & 主题 Keep
访客数 访问量