TypeReference需用匿名子类写法以保留泛型信息,因Java泛型擦除后仅能通过getGenericSuperclass()获取真实类型;错误写法会导致反序列化失败或类型丢失。

FastJSON 中使用 TypeReference 主要为了解决泛型擦除问题,让反序列化能正确还原带泛型的复杂类型(比如 List<User>、Map<String, List<Order>> 或嵌套响应类)。直接用 new TypeReference<Response>() {} 是关键,注意必须是**匿名子类**写法,否则运行时类型信息丢失,反序列化会失败或变成 LinkedHashMap。
为什么必须用匿名子类写法
Java 泛型在编译后被擦除,TypeReference 依赖匿名子类的 getGenericSuperclass() 获取真实泛型签名。如果写成 TypeReference<Response>.class 或普通变量引用,JVM 拿不到泛型参数,FastJSON 就无法推断目标类型。
- ✅ 正确:
new TypeReference<List<User>>() {} - ❌ 错误:
TypeReference<List<User>> type = new TypeReference<List<User>>();(没匿名子类) - ❌ 错误:
(TypeReference) TypeReference.class(完全无效)
反序列化常见复杂结构示例
假设服务返回 JSON 形如:{"code":200,"data":{"users":[{"id":1,"name":"张三"}]}},对应响应类:
public class ApiResponse<T> {
private int code;
private T data;
// getter/setter
}
public class User { private long id; private String name; }
反序列化写法:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
立即学习“Java免费学习笔记(深入)”;
- 解析整个响应:
ApiResponse<List<User>> res = JSON.parseObject(json, new TypeReference<ApiResponse<List<User>>>() {}); - 只解析 data 字段:
List<User> users = JSON.parseObject(jsonObject.getString("data"), new TypeReference<List<User>>() {}); - 多层嵌套 Map:
Map<String, Map<String, List<Product>>> map = JSON.parseObject(json, new TypeReference<Map<String, Map<String, List<Product>>>>() {});
注意事项和常见坑
FastJSON 1.x 版本(如 1.2.83)对 TypeReference 支持稳定,但需确保目标类有默认构造器、字段可访问(public 或有 getter/setter),且不依赖 JDK 17+ 的密封类等新特性。
- 如果反序列化后字段为 null,先检查类字段名是否与 JSON key 完全一致(默认大小写敏感,可用
@JSONField(name="user_id")映射) - 避免在 Lambda 或静态上下文中创建
TypeReference匿名类——可能因类加载器问题导致类型信息不可达 - FastJSON 2.x 已改用
TypeToken(兼容 Gson 风格),若升级需迁移写法:TypeToken<List<User>> token = new TypeToken<>(){};
替代方案:用泛型方法封装更安全
为减少重复代码和手误,可封装工具方法:
public static <T> T parseObject(String text, Class<T> clazz) {
return JSON.parseObject(text, clazz);
}
public static <T> T parseObject(String text, TypeReference<T> type) {
return JSON.parseObject(text, type);
}
// 调用:parseObject(json, new TypeReference<ApiResponse<List<User>>>() {});
这样既保持语义清晰,又避免每次手写冗长的匿名类。

















