jackson泛型反序列化需显式传递类型信息,推荐用typereference(){};或封装工具方法readvalueaslist(json, user.class);也可定义pojo如userlistresponse封装list。

Java 泛型擦除后,Jackson 默认无法知道你想要的 List<t></t> 中的 T 具体类型,所以反序列化时会把每个元素当成通用的 LinkedHashMap(因为 JSON 对象映射到 Java 默认就是 Map)。解决的核心是:**告诉 Jackson 具体的泛型类型信息**。
使用 TypeReference 显式传递泛型类型
这是最常用、最推荐的方式。Jackson 的 ObjectMapper.readValue() 有接受 TypeReference 的重载方法,它能保留泛型的运行时信息。
- 不要写
objectMapper.readValue(json, List.class)—— 这会丢失T信息 - 改用
objectMapper.readValue(json, new TypeReference<list>>() {})</list> - 注意:必须用匿名子类写法
new TypeReference<...>() {}</...>,否则类型信息仍会被擦除
封装成工具方法避免重复写 TypeReference
每次都要写 new TypeReference<list>>() {}</list> 比较啰嗦,可以封装一个泛型工具方法:
public <t> List<t> readValueAsList(String json, Class<t> elementType) throws JsonProcessingException {</t></t></t>- 内部用
objectMapper.readValue(json, objectMapper.getTypeFactory().constructCollectionType(List.class, elementType)) - 这样调用就变成
readValueAsList(json, User.class),简洁且类型安全
定义专门的包装类(适合固定结构)
如果这个 List<t></t> 总是和某个业务场景强绑定,比如“用户列表响应”,可以直接定义一个 POJO:
public class UserListResponse { private List<user> data; ... }</user>- 然后直接
objectMapper.readValue(json, UserListResponse.class) - Jackson 能通过字段类型推断出
List<user></user>,无需额外类型参数
检查 ObjectMapper 配置是否影响泛型处理
极少数情况下,自定义配置可能干扰类型解析:
- 确认没启用
DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY(它会让数组反序列化行为异常) - 避免全局注册不兼容泛型的模块(如某些旧版 jackson-datatype-guava 的配置)
- 默认配置下,只要传了正确的
TypeReference或构造的JavaType,就不会退化为LinkedHashMap
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











