【Java踩坑笔记】49_序列化版本号serialVersionUID不写会怎样?

📅 2026/7/16 23:59:14 👁️ 阅读次数 📝 编程学习
【Java踩坑笔记】49_序列化版本号serialVersionUID不写会怎样?

49 | 序列化版本号 serialVersionUID 不写会怎样?

摘要Serializable类不写serialVersionUID,JVM 会根据类结构自动生成一个。类结构稍有变化,自动生成的 UID 就变了,反序列化直接失败。


一、问题现象

// ❌ 没写 serialVersionUIDclassUserimplementsSerializable{privateLongid;privateStringname;}

把对象序列化到文件,然后给User加一个字段:

classUserimplementsSerializable{privateLongid;privateStringname;privateIntegerage;// 新增字段}

再反序列化:InvalidClassException


二、踩坑现场

场景:微服务间用 JDK 序列化传输

// ❌ 没写 serialVersionUID,发版后反序列化失败classOrderDTOimplementsSerializable{privateLongorderId;privateLonguserId;}

服务 A 发版(加了字段),服务 B 没发版,服务 B 反序列化失败。


三、原理解析

3.1 serialVersionUID 的作用

// 反序列化时会检查:// 字节流里的 serialVersionUID == 当前类的 serialVersionUID?// 相等 → 继续反序列化// 不相等 → InvalidClassException

3.2 不写时 JVM 怎么生成?

JVM 根据类的结构(字段、方法、修饰符…)计算一个哈希值。

问题:只要类结构稍有变化(加字段、改方法),哈希值就变。

// 版本 1(没写 serialVersionUID)classUserimplementsSerializable{privateLongid;}// 版本 2(加字段,自动生成的 UID 变了)classUserimplementsSerializable{privateLongid;privateStringname;// 新增}// 反序列化版本 1 的字节流 → InvalidClassException

四、正确写法

4.1 实现 Serializable 就写 serialVersionUID

// ✅ 正确:明确指定 serialVersionUIDclassUserimplementsSerializable{privatestaticfinallongserialVersionUID=1L;privateLongid;privateStringname;}

版本兼容规则

  • 字段只增不减 →serialVersionUID不变,反序列化兼容
  • 字段删除或类型改变 →serialVersionUID+1,不兼容

4.2 IDEA 自动生成

右键 → Generate → serialVersionUID
(需开启Serializable class without serialVersionUID警告)

4.3 不需要 JDK 序列化的场景

// ✅ JSON 序列化(Jackson)不依赖 serialVersionUID// 所以 DTO 如果只用 JSON 传输,不写也没关系classUser{privateLongid;privateStringname;}

:如果不确定未来会不会用 JDK 序列化(如放入HttpSession、用ObjectOutputStream),还是写上。


五、最佳实践

✅ Serializable 使用的 3 条铁律

  1. 实现Serializable必须写serialVersionUID
  2. 字段只增不减时serialVersionUID不变(兼容)
  3. 如果确定只用 JSON 序列化,可以不写(但写上更保险)

🔍 如何快速发现漏写?

IDEA 开启Serializable class without serialVersionUID警告(默认开启)。


六、小结

  • 不写serialVersionUID,JVM 根据类结构自动生成
  • 类结构稍有变化,自动生成的 UID 就变,反序列化失败
  • 实现Serializable必须写serialVersionUID
  • 字段只增不减 → UID 不变(兼容)
  • JSON 序列化(Jackson)不依赖serialVersionUID

第七辑完。—— 下一篇进入第八辑:综合实战篇,首篇:一次生产 OOM 排查实录。