java对象序列化需显式实现serializable接口并手动调用objectoutputstream.writeobject()和objectinputstream.readobject(),static/transient字段不参与,父类未实现则其字段不序列化,建议显式声明serialversionuid以避免invalidclassexception。

Java 对象序列化通过 Serializable 接口落地,核心是“声明许可 + 手动触发 + 规则约束”,不是加个接口就自动生效,而是一套需主动配合、有明确边界的机制。
让类实现 Serializable 接口
这是强制前提,不实现直接报错:
- 只需在类声明后添加
implements Serializable,该接口是空标记接口,无任何方法 - 未实现时调用
ObjectOutputStream.writeObject()会立即抛出NotSerializableException - 父类未实现该接口,子类即使实现了,父类字段也不会被序列化(除非父类提供可访问的无参构造器,且子类自行处理)
显式定义 serialVersionUID
这不是语法要求,但属于关键实践,直接影响反序列化成败:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 建议始终声明
private static final long serialVersionUID = 1L;(推荐用 IDE 自动生成唯一值) - 不声明时 JVM 会基于类名、字段、方法等生成哈希值,类结构稍作修改(如增删字段、改访问修饰符)就可能改变该值
- 反序列化时若
serialVersionUID不匹配,抛出InvalidClassException,导致数据无法还原
控制哪些字段参与序列化
默认规则下,并非所有字段都会被写入字节流:
- static 字段跳过:属于类而非实例,不保存状态
-
transient 字段跳过:适用于密码、线程、Socket、临时缓存等不可或不应持久化的字段,反序列化后为默认值(
null、0、false) -
字段类型必须可序列化:如果某个引用字段(如自定义类)未实现
Serializable,也会触发NotSerializableException
用 ObjectOutputStream 和 ObjectInputStream 完成读写
接口只是“开门许可”,真正操作靠这两类流:
- 序列化:用
ObjectOutputStream包装底层输出流(如FileOutputStream或ByteArrayOutputStream),再调用writeObject(obj) - 反序列化:用
ObjectInputStream包装对应输入流(如FileInputStream或ByteArrayInputStream),调用readObject()并强转为目标类型 - 注意捕获
IOException和ClassNotFoundException(后者在反序列化时找不到类定义会抛出)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










