对象序列化是将Java对象状态转为字节流以实现跨时间/空间持久化或传输,反序列化则还原对象;需实现Serializable接口,注意transient、static字段不参与、父类构造要求及serialVersionUID版本控制。

OOP对象序列化,就是把内存中一个活的Java对象“拍个照”,变成一串可存储、可传输的字节流;反序列化则是用这张“照片”重新还原出原来那个对象。它不是保存代码,而是保存对象**此刻的状态**——包括字段值、引用关系,甚至嵌套对象的完整结构。
为什么Java需要对象序列化
Java对象天生只存在于JVM内存里,程序一关就没了。但现实场景常要求对象“跨时间”或“跨空间”存在:
- 把用户登录态存到文件或Redis里,下次启动还能认出是谁
- 微服务之间传订单对象,不能只传ID,得把整个Order实例送过去
- RMI远程调用时,参数和返回值必须能打包发走
- 做深拷贝——new一个新对象并递归复制所有引用对象,一行writeObject就能搞定
怎么让一个类支持序列化
只需让类实现red">Serializable接口,它是个空标记接口,不强制你写任何方法。JVM看到这个标记,就知道:“哦,这个类允许被序列化”。
但有三点必须注意:
立即学习“Java免费学习笔记(深入)”;
- 所有非static、非transient字段都会被默认序列化;static属于类,transient表示“别管我”,这两类字段反序列化后是默认值(0、null、false)
- 父类没实现Serializable?那父类字段不会被保存,反序列化时靠父类无参构造器初始化(所以父类最好有无参构造)
- 如果类后续会修改(比如加字段、改类型),强烈建议显式声明private static final long serialVersionUID = 1L;,否则版本不匹配直接抛InvalidClassException
基本操作:两行代码完成持久化
序列化到文件:
```java
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {
oos.writeObject(new User("李四", 30));
}
反序列化读回来:
```java
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {
User u = (User) ois.readObject(); // 类型需一致
}
注意:readObject()返回Object,必须手动强转;且该类在反序列化时必须在classpath中存在,否则报ClassNotFoundException。
它和数据库存对象有什么区别
数据库存的是结构化数据(字段→列),本质是把对象“拆开存”;序列化是把整个对象图原样封成字节流,“打包存”。前者便于查询和关联,后者强调状态保真与快速重建。比如缓存一个计算结果复杂的报表对象,序列化存Redis比查库再组装快得多。
基本上就这些。不复杂但容易忽略细节,尤其是serialVersionUID和transient的配合使用。










