Java反射获取泛型类型须用getGenericSuperclass/getGenericInterfaces,判别ParameterizedType后调用getActualTypeArguments;WildcardType与TypeVariable需instanceof区分,仅Class和ParameterizedType可安全转为运行时类。

Java 反射获取父类和接口的泛型类型,核心在于用对方法、判对类型、递归处理嵌套结构。直接调用 getSuperclass() 或 getInterfaces() 会丢失泛型信息,必须使用带 Generic 前缀的方法。
获取父类泛型类型(getGenericSuperclass)
子类若显式指定了父类的泛型实参(如 class A extends List<string></string>),字节码中会保留该信息,反射可读取:
- 调用
clazz.getGenericSuperclass(),返回值是Type,不是Class - 检查是否为
ParameterizedType:只有这时才表示父类以具体泛型形式被继承 - 强转后调用
getActualTypeArguments(),得到Type[]数组 - 数组每个元素可能是:
Class(如String.class)、ParameterizedType(如Map<string integer></string>)、TypeVariable(如T,无法运行时确定)、WildcardType(如? extends Number)
获取接口泛型类型(getGenericInterfaces)
逻辑与父类类似,但需遍历所有接口:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 调用
clazz.getGenericInterfaces(),返回Type[] - 逐个判断每个元素是否为
ParameterizedType - 对匹配项调用
getActualTypeArguments()提取泛型参数 - 注意:接口可能本身是泛型定义(如
interface Container<t></t>),此时需结合getTypeParameters()解析声明处的TypeVariable及其getBounds()
区分 WildcardType 和 TypeVariable
二者都出现在泛型边界中,但语义不同,必须用 instanceof 明确区分:
立即学习“Java免费学习笔记(深入)”;
-
WildcardType出现在使用位置,如? super Integer;调用getLowerBounds()得到{Integer.class},getUpperBounds()默认返回{Object.class} -
TypeVariable出现在声明位置,如<T extends Comparable<T> & Serializable>;调用getName()得到"T",getBounds()返回约束类型数组(含Comparable<T>这类仍含TypeVariable的嵌套结构,需递归解析)
安全提取运行时可用的具体 Class
并非所有泛型都能还原成 Class,只对明确指定的实参才可靠:
- 若
Type是Class,直接强转使用 - 若为
ParameterizedType,可递归提取其getRawType()(如Map.class),或进一步解析其getActualTypeArguments() - 跳过
TypeVariable和WildcardType—— 它们代表编译期抽象,无对应运行时类对象 - 典型误用:对
class A extends B<T>调用反射,T是TypeVariable,无法获得具体类型

















