java序列化本质是对象与字节流的互转:序列化将对象转为字节流以持久化或传输,反序列化则还原为对象;必须满足三前提——类实现serializable接口、非transient非static字段类型可序列化、父类无serializable时须提供无参构造器。

直接上手学,别绕弯子。Java序列化本质就两件事:把对象变成字节流(序列化),再把字节流变回对象(反序列化)。掌握它不靠死记,靠理解关键点+动手写几遍。
先搞懂三个硬性前提
没这三条,代码一跑就抛 NotSerializableException:
- 目标类必须实现 java.io.Serializable 接口(空接口,只起标记作用);
- 所有非 transient、非 static 的实例字段,其类型也得可序列化(比如 String、List、自定义类等);
- 如果父类没实现 Serializable,子类序列化时,父类字段不会被保存,且反序列化时会调用父类无参构造器——所以父类必须有无参构造器,否则直接报 InvalidClassException。
写一个能跑通的最小闭环
两步到位,5分钟搞定:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
第一步:定义类,显式加
serialVersionUID(别用 IDE 自动生成的随机值,自己写个固定数字,比如private static final long serialVersionUID = 1L;); -
第二步:用
ObjectOutputStream写入文件,用ObjectInputStream读出来。注意流必须 try-with-resources 或手动 close,否则可能写不全或读失败。
示例片段(User 类 + 序列化/反序列化方法)可直接粘贴运行,不用改就能看到对象“存进去又活过来”。
避开高频踩坑点
这些不是细节,是上线后真会炸的雷:
-
敏感字段用
transient:密码、token、临时缓存等,加了就不进字节流; - serialVersionUID 必须显式声明:否则不同 JDK 或编译环境生成的默认值不同,跨服务反序列化必失败;
-
集合类字段要小心初始化:比如
private List<string> tags;</string>反序列化后是 null,建议在声明时初始化:private List<string> tags = new ArrayList();</string>; - 避免在 readObject/writeObject 里做耗时操作:比如远程调用、DB 查询,反序列化是同步阻塞的,容易拖垮整个请求链路。
什么时候该换方案
原生序列化够用,但不适合所有场景:
- 需要高性能或小体积 → 用 Protobuf 或 JSON(Jackson/Gson);
- 要精细控制字段读写逻辑 → 实现 Externalizable,自己写
writeExternal/readExternal; - 微服务间通信 → 优先选 HTTP+JSON,别用 Java 原生序列化(不跨语言、有安全风险);
- Redis 存对象 → 看清客户端默认序列化方式(Lettuce 默认用 JDK,推荐切到 Jackson2JsonRedisSerializer)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










