java泛型类型擦除后仍可通过getgenerictype()和signature属性获取真实泛型信息:parameterizedtype解析实参、typevariable结合继承链绑定具体类型、wildcardtype提取边界,递归构建generictypeinfo供精准校验。

Java 的类型擦除确实让运行时拿不到泛型实际类型,但别急——Signature 属性在字节码里悄悄保留了泛型签名,反射 API 能读它。这就为动态校验器提供了关键突破口:不靠 getClass().getTypeParameters()(那早被擦没了),而靠 Field.getGenericType() + ParameterizedType 解析 Signature。
识别字段真实泛型类型:从 getGenericType() 入手
普通 field.getType() 返回的是擦除后的原始类型(比如 java.util.List),但 field.getGenericType() 会返回带参数信息的类型对象,前提是该字段声明时用了泛型(如 List<user></user> 或 Map<string orderdetail></string>)。
- 若返回值是
ParameterizedType,说明字段是参数化类型,可安全调用getActualTypeArguments()获取泛型实参数组 - 若返回值是
TypeVariable(如T),说明字段依赖类级泛型参数(如class Dto<t> { T data; }</t>),此时需结合类的getGenericSuperclass()或构造器泛型上下文推导 - 若返回值是
WildcardType(如? extends Number),需提取上界/下界做宽松校验
递归解析嵌套泛型结构:支持 List
泛型实参本身可能是复合类型。例如 List<map user>></map> 中,第二个实参是 Map<string user></string>,它自己又是 ParameterizedType。
- 写一个递归方法,对每个
Type实例判断类型并分发处理:ParameterizedType→ 拆出实参继续递归;Class→ 记录为终端类型(如String.class);WildcardType→ 提取getUpperBounds()用于校验范围 - 把解析结果组织成轻量结构体(如
GenericTypeInfo),包含主类型、泛型参数列表、是否可为空等元信息,供后续校验逻辑使用 - 注意数组类型:
User[]在getGenericType()中表现为GenericArrayType,需用getGenericComponentType()获取元素类型
绑定运行时类型实参:解决泛型类继承场景下的 T 泛型丢失问题
当 DTO 是泛型类子类(如 class UserDto extends BaseDto<user></user>),父类字段 T data 的 getGenericType() 仍是 TypeVariable,但通过子类的泛型父类签名可以还原。
- 调用
dtoClass.getGenericSuperclass(),若为ParameterizedType,则其getActualTypeArguments()就是子类对父类泛型参数的具体绑定 - 建立字段名 → 类型变量名 → 实际类型映射表。例如父类字段
data声明为T,而UserDto绑定T = User,即可将data字段的泛型类型确定为User.class - 对多层继承(如
A<x></x>→B<y> extends A<y></y></y>→C extends B<string></string>),需逐级向上解析泛型父类,直到拿到最终实参
校验器执行阶段:按解析出的泛型结构生成动态规则
有了准确的泛型类型树,就能做精准校验,而不是全用 Object 粗放处理:
- 对
List<user></user>字段:校验值是否为Collection,且每个元素能被User的校验器处理(支持嵌套递归校验) - 对
Optional<localdatetime></localdatetime>:检查非空时触发LocalDateTime的时间格式/范围校验 - 对
Map<string extends product></string>:键必须为字符串,值必须是Product或其子类实例,并触发对应子类校验逻辑 - 自动跳过未提供校验器的泛型类型(如自定义泛型
Result<t></t>),只校验已注册的终端类型(T若被绑定为Order,则走Order校验器)
Signature 属性不是黑盒,它是编译器留给反射的“便签”。只要绕过 getType() 的陷阱,坚持用 getGenericType() 链路,再辅以继承上下文回溯,就能稳稳抓住泛型的真实面貌。校验器也就从“只能校基本类型”升级为“懂嵌套、知边界、会递归”的高动态能力。










