问题:Java泛型擦除后如何通过反射获取泛型信息? 答:虽然 Java 在编译时会进行类型擦除(Type Erasure),将泛型替换为原始类型(通常是 Object 或边界类型),但某些情况下泛型信息会被保留在字节码中,可以通过反射获取: 1. 获取父类/接口的泛型参数 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.List; // 继承泛型类时指定具体类型 public class StringList extends ArrayList {} public class GenericReflectionDemo { public static void main(String[] args) { // 获取父类的泛型参数 Class clazz = StringList.class; Type genericSuperclass = clazz.getGenericSuperclass(); if (genericSuperclass instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericSuperclass; Type[] actualTypeArgs = pt.getActualTypeArguments(); for (Type type : actualTypeArgs) { System.out.println("泛型参数类型: " + type); // 输出: class java.lang.String } } } } 2. 获取字段的泛型类型 Java 1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class GenericField { private List names; private Map mapping; } // 获取字段泛型 Field field = GenericField.class.getDeclaredField("names"); Type genericType = field.getGenericType(); if (genericType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericType; System.out.println("字段泛型参数: " + Arrays.toString(pt.getActualTypeArguments())); // 输出: [class java.lang.String] } 3. 获取方法参数的泛型类型 Java 1 2 3 4 public void process(List items, Map map) {} Method method = clazz.getMethod("process", List.class, Map.class); Type[] paramTypes = method.getGenericParameterTypes(); 4. 核心 API 总结 反射方法 用途 getGenericSuperclass() 获取父类的泛型类型 getGenericInterfaces() 获取接口的泛型类型 Field.getGenericType() 获取字段的泛型类型 Method.getGenericReturnType() 获取返回值的泛型类型 Method.getGenericParameterTypes() 获取方法参数的泛型类型 ParameterizedType.getActualTypeArguments() 获取实际泛型参数 ⚠️ 限制:局部变量和方法参数的泛型信息在运行时是完全擦除的,无法通过反射获取。