Fastjson 的 TypeReference 通过匿名子类保留泛型签名,但仅对编译期已知类型有效;运行时动态类型需用带参构造器 new TypeReference(actualClass) {} 显式传入最内层 Class,且从 1.2.9+ 支持,外层结构仍须完整写出。

Fastjson 的 TypeReference 是解决多层嵌套泛型反序列化的关键工具,但直接写 new TypeReference<response>>>() {}</response> 往往不够——尤其当 T 是运行时才确定的具体类型(比如 UserDTO 或 Order)时,泛型擦除会让 Fastjson 无法识别最内层类型,导致 data 字段解析成 JSONObject 而非真实对象,强转即抛 ClassCastException。
为什么单层 TypeReference 对 Response 失效
Java 编译后会擦除所有泛型信息。虽然 TypeReference 利用匿名子类保留了字节码中的泛型签名,但它只能“看到”编译期已知的完整类型结构。如果代码里写的是:
-
JSON.parseObject(json, new TypeReference<response>>>() {})</response>→ ✅ 可行,因为UserDTO是具体类,签名完整 -
JSON.parseObject(json, new TypeReference<response>>>() {})</response>→ ❌ 编译不通过或运行时T被擦成Object,Page.records仍为JSONObject
正确传入运行时确定的泛型参数
当 T 来自方法参数、配置或反射结果时,必须用 TypeReference 的带参构造器显式注入实际类型:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- Fastjson 支持
new TypeReference<response>>>(actualClass) {}</response>,其中actualClass是UserDTO.class这样的Class对象 - 示例:
Response
> result = JSON.parseObject(json, new TypeReference >>(UserDTO.class) {}); - 注意:这个构造器从 Fastjson 1.2.9+ 开始支持,且只作用于最内层泛型变量(即
T),外层结构(Response<page>></page>)仍需完整写出
三层及以上嵌套的典型写法
面对 Response<page>>></page> 这类结构,不要试图嵌套多层泛型变量,而是逐级“展开”并指定最末端的实际类型:
立即学习“Java免费学习笔记(深入)”;
- 错误:
new TypeReference<response>>>>(Item.class) {}</response>——List<t></t>中的T可被替换,但Page和List本身不能动态化 - 正确:
new TypeReference<response>>>>() {}</response>(全部写死) - 更灵活:
new TypeReference<response>>>>() {}</response>+ 提前构建ParameterizedType(适用于高度动态场景)
避免重复反射开销:缓存 Type 实例
TypeReference.getType() 每次调用都会触发反射解析,高频调用时建议缓存:
- 声明为
static final: private static final Type USER_RESPONSE_TYPE = new TypeReference>>() {}.getType(); - 使用时直接传入:
Response
> r = JSON.parseObject(json, USER_RESPONSE_TYPE); - 若类型动态,可基于
Class参数生成并缓存在ConcurrentHashMap中,避免重复解析

















