java反射不直接做json反序列化,而是为jackson等框架提供运行时类型信息(如泛型、注解),支撑其自动构造对象;关键在于通过getgenerictype()等方法还原擦除的泛型,并结合解析器完成类型匹配与赋值。

Java 反射机制本身不直接做 JSON 反序列化,但它为反序列化框架(如 Jackson、Gson)提供了核心能力:在运行时获取字段声明类型、泛型信息、注解等元数据,从而准确构造目标对象。关键不是“用反射手动写反序列化逻辑”,而是理解框架如何利用反射支撑类型安全的自动反序列化。
获取字段真实类型(含泛型)
反射能突破编译期擦除,还原泛型实际参数。比如 private List<user> users;</user>,通过 Field.getGenericType() 得到 ParameterizedType,再调用 getActualTypeArguments() 拿到 User.class。
-
普通类型:直接用
field.getType()获取 Class 对象(如String.class、int.class) -
参数化类型:判断是否为
ParameterizedType,提取原始类型(ArrayList.class)和实际类型参数(User.class) -
数组类型:用
field.getType().getComponentType()获取元素类型 - 通配符/类型变量:需结合类的泛型声明上下文推导(较复杂,主流框架已封装处理)
结合 JSON 解析器完成类型匹配
反序列化过程是“解析 JSON → 推导目标字段类型 → 实例化并赋值”。反射提供类型信息,解析器负责执行:
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
- 读取 JSON 字符串,识别结构(对象、数组、字符串等)
- 遍历目标类所有字段,用反射获取其类型;若字段是
List<order></order>,就为每个数组元素创建Order实例 - 对嵌套对象递归调用相同逻辑(反射获取其字段类型,再解析对应 JSON 子结构)
- 基本类型和包装类(
int/Integer)由解析器内置转换,无需额外反射
处理常见类型细节
真实场景中需注意几类易出错的类型,反射是解决它们的基础:
-
接口或抽象类字段:如
private List<animal> pets;</animal>,仅靠getType()得到List.class,无法知道具体实现类。需依赖 JSON 中的类型标识(如@class字段)或注册默认实现(Jackson 的@JsonDeserialize) -
泛型擦除后的运行时类型丢失:反射通过
getGenericType()恢复,但前提是字段声明中明确写了泛型(List<string></string>),而非仅在局部变量中使用 -
私有字段访问:调用
field.setAccessible(true)绕过访问控制,否则无法为 private 字段赋值 -
无参构造函数要求:多数框架需通过
clazz.getDeclaredConstructor().newInstance()创建实例,若类无 public 无参构造器会失败
实际开发建议
不建议手写完整反序列化器。应优先使用成熟库,并理解其反射运用逻辑:
- Jackson 默认启用
ObjectMapper的反射能力,配合@JsonProperty、@JsonCreator等注解控制行为 - Gson 需显式传入
TypeToken<list>>(){}.getType()</list>来保留泛型信息,本质仍是反射提取 - 自定义反序列化器(如实现
JsonDeserializer<t></t>)时,可调用context.getContextualType()获取当前字段的完整类型信息 - 避免过度依赖反射性能——对高频调用场景,可缓存
Field、Constructor对象,或预生成字节码(如 FastJSON2 的 ASM 优化)
不复杂但容易忽略:反射只是桥梁,真正让 JSON 转成正确 Java 对象的,是类型信息 + 解析策略 + 实例构造三者的协同。掌握字段类型获取这一环,就抓住了自动化反序列化的关键支点。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










