Java反射中需用getGenericParameterTypes()配合Type体系解析泛型参数,如ParameterizedType的getActualTypeArguments()获取List中的String等实际类型参数。

Java 反射无法直接通过 Method#getParameterTypes() 获取泛型参数类型(如 List 中的 String),因为该方法只返回擦除后的原始类型(如 List.class)。要获取泛型参数类型,必须使用 Method#getGenericParameterTypes(),并配合 Type 体系(尤其是 ParameterizedType)进行解析。
获取方法参数的泛型类型(基础步骤)
调用 getGenericParameterTypes() 返回的是 Type[] 数组,每个元素可能是:
-
Class:非泛型类型(如String、int) -
ParameterizedType:带实际类型参数的泛型类型(如List、Map) -
WildcardType:通配符类型(如? extends Number) -
TypeVariable:类型变量(如方法声明中的中的void foo(T t) T)
解析 ParameterizedType 获取实际类型参数
当某个参数类型是 ParameterizedType 时,可调用其 getActualTypeArguments() 获取泛型实参数组。注意:每个实参本身仍是 Type,可能需递归解析(例如嵌套泛型 Map)。
示例代码片段:
Method method = clazz.getDeclaredMethod("process", List.class, Map.class);
Type[] genericParams = method.getGenericParameterTypes();
for (int i = 0; i
处理泛型方法声明中的类型变量(如 T get())
若方法自身是泛型方法(签名含 ),其参数或返回值中出现的 T 是 TypeVariable,此时无法在运行时得知具体绑定类型(因类型擦除且未提供上下文)。但可通过 TypeVariable#getBounds() 获取上界(默认为 Object)。
例如: 中,t 的类型是 TypeVariable,其 getBounds() 返回 [CharSequence.class]。
注意边界情况和常见陷阱
- 只有**源码中明确写出泛型**(如
void f(List)才能反射获取到list) String;若写成void f(List list),则只能得到List.class - 匿名内部类、Lambda 表达式、局部变量中的泛型信息**不会保留**在字节码中,反射不可见
- 数组泛型(如
List)需先识别为[] GenericArrayType,再调用getGenericComponentType()解析元素类型 - 确保使用
getDeclaredMethod并传入正确的参数类型(擦除后类型),否则可能抛NoSuchMethodException
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











