java泛型运行时被擦除,反序列化需显式提供类型信息;jackson用typereference可保留泛型结构,自定义泛型类需getter/setter或@jsonproperty注解,避免原生serializable,复杂嵌套可用javatype。

Java 中泛型在运行时被擦除(Type Erasure),所以直接序列化泛型类对象(如 List<string></string>)后反序列化,会丢失具体类型信息,还原成原始类型(如 List),元素变成 Object。要正确保留泛型类型,关键不是“改泛型”,而是**在反序列化时主动提供类型信息**。
用 Jackson 的 TypeReference 保留泛型结构
Jackson 是最常用且对泛型支持友好的 JSON 库。它不依赖运行时泛型,而是靠你显式传入类型描述。
- 序列化普通泛型对象无需特殊处理:
mapper.writeValueAsString(list)能正常输出 JSON - 反序列化时必须用
TypeReference告诉 Jackson 目标类型:List<user> users = mapper.readValue(json, new TypeReference<list>>() {});</list></user> - 注意:
TypeReference必须是匿名子类(带{}),否则无法捕获泛型签名
自定义泛型类需确保字段可被 Jackson 识别
如果你的泛型类像 Result<t></t>,要让 Jackson 正确反序列化 T,得满足:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 泛型字段有 public getter/setter 或使用
@JsonProperty - 避免仅靠字段名推断(比如字段叫
data,但没注解或 setter,Jackson 可能忽略) - 推荐写法示例:
public class Result<t> { @JsonProperty("data") private T data; // 必须有 getter 和 setter,即使泛型是 T public T getData() { return data; } public void setData(T data) { this.data = data; } }</t> - 反序列化时仍需
TypeReference<result>></result>显式指定
避免用 Java 原生 Serializable + 泛型类直接反序列化
Java 原生序列化(ObjectOutputStream / ObjectInputStream)无法恢复泛型类型参数。
- 即使类实现了
Serializable,反序列化后List<string></string>变成List,遍历时元素是Object,需手动强转 - 没有安全机制校验类型,容易
ClassCastException - 除非业务强依赖二进制兼容和原生协议,否则不建议用于含泛型的数据传输
复杂嵌套泛型可用 ResolvedType(Jackson 2.12+)
当泛型含通配符、多层嵌套(如 Map<string list>>></string>),可借助 JavaType 构建精确类型:
- 用
mapper.getTypeFactory()创建:JavaType type = mapper.getTypeFactory() .constructParametricType(Map.class, SimpleType.construct(String.class), mapper.getTypeFactory().constructCollectionLikeType(List.class, mapper.getTypeFactory().constructType(Optional.class).getContentType())); - 再传给
readValue(json, type) - 适合框架封装或动态类型场景,日常开发用
TypeReference更简洁
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










