【Java踩坑笔记】49_序列化版本号serialVersionUID不写会怎样?
49 | 序列化版本号 serialVersionUID 不写会怎样摘要Serializable类不写serialVersionUIDJVM 会根据类结构自动生成一个。类结构稍有变化自动生成的 UID 就变了反序列化直接失败。一、问题现象// ❌ 没写 serialVersionUIDclassUserimplementsSerializable{privateLongid;privateStringname;}把对象序列化到文件然后给User加一个字段classUserimplementsSerializable{privateLongid;privateStringname;privateIntegerage;// 新增字段}再反序列化InvalidClassException。二、踩坑现场场景微服务间用 JDK 序列化传输// ❌ 没写 serialVersionUID发版后反序列化失败classOrderDTOimplementsSerializable{privateLongorderId;privateLonguserId;}服务 A 发版加了字段服务 B 没发版服务 B 反序列化失败。三、原理解析3.1 serialVersionUID 的作用// 反序列化时会检查// 字节流里的 serialVersionUID 当前类的 serialVersionUID// 相等 → 继续反序列化// 不相等 → InvalidClassException3.2 不写时 JVM 怎么生成JVM 根据类的结构字段、方法、修饰符…计算一个哈希值。问题只要类结构稍有变化加字段、改方法哈希值就变。// 版本 1没写 serialVersionUIDclassUserimplementsSerializable{privateLongid;}// 版本 2加字段自动生成的 UID 变了classUserimplementsSerializable{privateLongid;privateStringname;// 新增}// 反序列化版本 1 的字节流 → InvalidClassException四、正确写法4.1 实现 Serializable 就写 serialVersionUID// ✅ 正确明确指定 serialVersionUIDclassUserimplementsSerializable{privatestaticfinallongserialVersionUID1L;privateLongid;privateStringname;}版本兼容规则字段只增不减 →serialVersionUID不变反序列化兼容字段删除或类型改变 →serialVersionUID1不兼容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 条铁律实现Serializable必须写serialVersionUID字段只增不减时serialVersionUID不变兼容如果确定只用 JSON 序列化可以不写但写上更保险 如何快速发现漏写IDEA 开启Serializable class without serialVersionUID警告默认开启。六、小结不写serialVersionUIDJVM 根据类结构自动生成类结构稍有变化自动生成的 UID 就变反序列化失败实现Serializable必须写serialVersionUID字段只增不减 → UID 不变兼容JSON 序列化Jackson不依赖serialVersionUID第七辑完。—— 下一篇进入第八辑综合实战篇首篇一次生产 OOM 排查实录。