当前位置: 首页 > news >正文

【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 排查实录。

http://www.jsqmd.com/news/1203184/

相关文章:

  • 【Atlas】HBase 表设计对 Atlas 性能有何影响?如何调优?
  • 相似度检索:原理、算法与应用实践
  • MonoGame 3D游戏开发完全指南:从零到一的跨平台游戏引擎实战
  • DINOv3:现代视觉基础模型架构设计与工程实践深度解析
  • API调用失败率下降92%的关键配置,Codex AI生产环境部署避坑清单,仅限本周开放
  • 2026 年广州独立能力培养训练营推荐:军博营地育人高效 - 松梢月冷
  • 增量游戏数据修改实战:LocalStorage与内存修改技术详解
  • 如何通过3个步骤找到最适合你硬件的本地AI模型
  • RA6M4开发板入门:从环境搭建到串口通信实践
  • 英雄联盟锤石下路配合指南:技能连招与对线压制技巧
  • 消费观里:女“自我取悦”是必修课;男 “自我压抑”是潜规则
  • 泰格豪雅中国官方售后服务中心|服务电话及24小时详细地址权威信息通知(2026年7月更新) - 亨得利官方服务中心
  • 本地化多模型AI测试环境搭建与主流模型能力对比实践
  • 离散数学 | 4 集合与集合运算
  • 2026 年广州夏令营哪家有军事训练内容:军博营地实训过硬 - 秋山寄远
  • 2026年度广东征收标准维权律师推荐榜单汇总 - 互联网科技品牌测评
  • 从零开始安装部署一个openclaw
  • 终极Windows防休眠指南:PowerToys Awake三步设置让电脑永不自动休眠
  • 别急着签合同!2026年广州建站平台推荐,先看这4个细节
  • 从SQL查询到数据洞察:SQLPad如何重构数据库交互体验
  • 揭秘AI推理加速革命:Ornith-1.0-9B-MTP-GGUF如何实现无损性能飞跃
  • 亲身到店体验徐州亨得利官方名表服务中心|详细地址与客服电话(2026年7月更新) - 亨得利官方博客
  • C++整数反转算法详解:从数学迭代到字符串转换的两种核心实现
  • 2026北京帝舵回收,闲置帝舵腕表长期搁置易贬值!毓典奢品汇专业鉴定估价,运动奢华腕表稳妥变现 - 奢品流通笔谈
  • 2026轴重检测仪十大品牌,浙江润鑫以稳定性能赢信赖,品质靠谱 - 品牌速递
  • FreeRTOS在STM32上的移植与优化实践
  • NAS一键部署AFFiNE:打造私有Notion+白板知识库
  • 深度解析TileLang:如何用30行代码实现高性能GPU算子?
  • 为什么Ornith-1.0-9B-MTP-GGUF的无损多令牌预测能实现1.7倍推理加速?
  • TLPI 第25 章 读书笔记:Process Termination