这是怎么做到的?反射不是运行时吗?运行时不是没有泛型吗?
网上看了一大堆
发现虽然泛型是被擦除了,存储的还是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()); } }
|