Java泛型因类型擦除导致Jackson反序列化时无法识别元素类型,需用TypeReference匿名子类、TypeFactory构建JavaType或包装类处理多态集合。

用 TypeReference 匿名子类(最常用)
适用于已知具体泛型类型、代码可编译期确定的场景(如 `List写法要点:
- 必须用 匿名内部类语法:`new TypeReference
- >() {}`(注意双大括号)
- 不能省略泛型参数,`new TypeReference
- () {}` 等价于 `List.class`,依然会丢失元素类型
- 双大括号内不要写任何逻辑(如构造器调用),避免内存泄漏或序列化问题
示例:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
String json = "[{\"name\":\"Alice\",\"age\":30}]";
List<User> users = objectMapper.readValue(json, new TypeReference<List<User>>() {});
用 TypeFactory 构建 JavaType(推荐用于泛型方法)
适用于需要封装通用工具方法的场景(如 `<T> List<T> readList(String json, Class<T> elementType)`),能绕过类型擦除限制。核心逻辑:
- 传入元素类型 `Class<T>`(如 `User.class`)
- 用 `objectMapper.getTypeFactory().constructCollectionType(List.class, elementType)` 构造出带泛型的 `JavaType`
- 再传给 `readValue` 方法
示例:
立即学习“Java免费学习笔记(深入)”;
public <T> List<T> readList(String json, Class<T> elementType) throws IOException {
JavaType type = objectMapper.getTypeFactory()
.constructCollectionType(List.class, elementType);
return objectMapper.readValue(json, type);
}
// 调用
List<User> users = readList(json, User.class);
嵌套泛型也一样处理
像 `Map- >` 这类多层泛型,仍需用 `TypeReference` 显式声明完整类型。
- 为每种业务类型定义一个具体包装类(如 `AccountLedgerList`),内部持 `List<AccountLedgerResponse> data`
- 在顶层响应类中,对该包装类字段标注 `@JsonTypeInfo` 和 `@JsonSubTypes`
- 确保包装类有无参构造器
正确写法:
Map<String, List<User>> map = objectMapper.readValue(json,
new TypeReference<Map<String, List<User>>>() {});
错误写法(只声明外层):
// ❌ 无效:List 的泛型未指定,等同于 List<Object>
new TypeReference<Map<String, List>>() {}
多态集合需配合包装类(非泛型类)
当 JSON 中有 `"method": "AccountLedger"` 这类字段决定 `data` 实际类型时,**不能**对 `List正确做法:
本质是把多态逻辑落在「可实例化的类」上,而非抽象的 `List
不复杂但容易忽略

















