Java对象序列化必须实现Serializable接口,否则抛NotSerializableException;需显式声明serialVersionUID、用transient修饰敏感字段;必须用try-with-resources同时管理FileOutputStream和ObjectOutputStream;路径用Paths.get()避免分隔符问题;读取前校验文件非空,捕获异常并提示格式不兼容;序列化非持久化银弹,仅适用于同JDK版本短期存储。

Java对象序列化保存前必须实现Serializable接口
不加这个接口,调用ObjectOutputStream写入时会直接抛出NotSerializableException。这不是可选步骤,是JVM强制校验——哪怕类里只有String字段也逃不掉。
实操建议:
- 在备忘录类(比如
Memo)声明处加上implements Serializable - 手动添加
private static final long serialVersionUID = 1L;,避免因类结构微调导致反序列化失败 - 敏感字段(如临时计算值、数据库连接)用
transient修饰,它们不会被写入文件
用ObjectOutputStream写文件要配对关闭FileOutputStream
只关ObjectOutputStream看似合理,但底层缓冲区可能没刷到磁盘,导致文件为空或损坏。常见现象是文件生成了,大小为0字节,或者下次读取时报StreamCorruptedException。
实操建议:
- 必须用
try-with-resources同时管理两个流:FileOutputStream和ObjectOutputStream - 不要自己调用
flush()——close()已隐含刷盘逻辑 - 路径别硬编码,用
Paths.get("memos.dat").toFile()更可靠,避开Windows/Linux路径分隔符问题
读取时ObjectInputStream可能抛ClassNotFoundException
反序列化时JVM需要原样加载类定义。如果程序重启后修改了Memo类(比如增删字段),又没更新serialVersionUID,就会报这个错;更隐蔽的是:把序列化文件拷到另一台机器运行,但目标环境没部署该类的.class文件。
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
实操建议:
- 读取前先检查文件是否存在且非空,空文件直接跳过反序列化
- 捕获
ClassNotFoundException和InvalidClassException,提示“备忘录数据格式不兼容”,而不是让程序崩溃 - 开发阶段可临时用
readUnshared()替代readObject(),减少共享引用引发的意外
序列化不是持久化银弹,小项目够用,但别碰真实业务数据
Java原生序列化本质是把内存对象快照直写二进制,它绑定具体JDK版本、类结构、甚至IDE编译器行为。你今天用JDK 17序列化的文件,明天换成JDK 21可能就打不开;换个IDE重新编译,serialVersionUID悄悄变了也未必察觉。
真正要长期存数据,得换方案:纯文本用Properties或JSON(gson/jackson),结构简单用CSV,再往后才是数据库。序列化只适合同一进程内短期传递,或本地开发调试时图省事。
现在你手里的memos.dat文件,只要没跨JDK大版本、没重构Memo类,就能稳稳读回来——但千万别把它放进用户交付包里当正式存储方案。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










