java中实现serializable接口是对象序列化与反序列化的基础,需显式定义serialversionuid,确保字段可序列化或用transient修饰,通过objectoutputstream/objectinputstream完成读写操作。

Java 中实现 Serializable 接口是进行对象序列化与反序列化的最基础方式,它本身是个空接口(标记接口),不定义任何方法,作用是告诉 JVM 该类的对象可以被转换为字节流。
实现 Serializable 接口的基本步骤
只需让类声明实现 java.io.Serializable 接口即可,通常建议显式定义一个 serialVersionUID 字段,避免因类结构变化导致反序列化失败:
- 在类中添加
private static final long serialVersionUID = 1L;(值可自定义,推荐用 IDE 自动生成) - 确保所有非静态、非瞬态(
transient)字段类型本身也支持序列化(即实现了Serializable) - 若存在不可序列化的字段(如线程、Socket、数据库连接等),用
transient修饰,它们不会被写入字节流
使用 ObjectOutputStream 和 ObjectInputStream 进行序列化与反序列化
序列化是将对象写入输出流,反序列化是从输入流还原对象。关键在于流必须是对象专用流:
- 序列化:用
ObjectOutputStream包装一个底层字节流(如FileOutputStream或ByteArrayOutputStream),调用writeObject(obj) - 反序列化:用
ObjectInputStream包装对应输入流(如FileInputStream或ByteArrayInputStream),调用readObject()并强制转为目标类型 - 注意:反序列化时类必须在类路径中可用,且
serialVersionUID必须匹配,否则抛出InvalidClassException
常见注意事项和陷阱
看似简单,但实际使用中容易踩坑:
-
static字段不会被序列化(属于类,不属于对象实例) -
transient字段跳过序列化,反序列化后为默认值(如null、0、false) - 父类未实现
Serializable,子类虽实现了,但父类的字段不会被序列化(除非父类也实现或提供无参构造器 + 自定义序列化逻辑) - 若需控制序列化过程(如加密、过滤敏感字段),可实现
writeObject和readObject私有方法
简单示例代码片段
假设有一个用户类:
<font color="#888">public class User implements Serializable {<br> private static final long serialVersionUID = 123456789L;<br> private String name;<br> private transient String password; // 不序列化<br> private int age;<br><br> // 构造器、getter/setter 省略<br>}</font>
序列化到文件:
<font color="#888">try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"))) {<br> oos.writeObject(new User("Alice", "123", 25));<br>}</font>
从文件反序列化:
<font color="#888">try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"))) {<br> User u = (User) ois.readObject(); // 注意强转<br> System.out.println(u.getName() + ", " + u.getPassword()); // password 为 null<br>}</font>
不复杂但容易忽略细节,关键是理解标记接口的作用、流的配合方式以及字段可见性对序列化结果的影响。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











