Java 序列化(Serialization) 是指把对象转换为字节流的过程,便于持久化存储或网络传输;**反序列化(Deserialization)**则是把字节流恢复为对象。
下面从原理、流程、关键机制、示例、注意事项几个方面系统说明。
Java 序列化依赖两个核心接口:
java.io.Serializable(标记接口,无方法)java.io.Externalizable(可自定义序列化过程)最常见的是 Serializable。
ObjectOutputStream:序列化(对象 → 字节流)ObjectInputStream:反序列化(字节流 → 对象)ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(obj);
JVM 做了什么?
Serializable
NotSerializableExceptiontransient、非 static 字段ObjectInputStream ois = new ObjectInputStream(inputStream);
Object obj = ois.readObject();
JVM 做了什么?
readResolve(),调用它import java.io.*;
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
private transient String password;
public User(String name, int age, String password) {
this.name = name;
this.age = age;
this.password = password;
}
@Override
public String toString() {
return name + ", " + age + ", " + password;
}
}
User user = new User("Tom", 18, "123456");
try (ObjectOutputStream oos =
new ObjectOutputStream(new FileOutputStream("user.obj"))) {
oos.writeObject(user);
}
try (ObjectInputStream ois =
new ObjectInputStream(new FileInputStream("user.obj"))) {
User user = (User) ois.readObject();
System.out.println(user);
}
输出:
Tom, 18, null
transient字段不会被序列化
private static final long serialVersionUID = 1L;
用于 版本一致性校验
反序列化时:
serialVersionUIDserialVersionUID 不一致InvalidClassException✅ 生产环境必须显式定义
| 关键字 | 是否序列化 |
|---|---|
| transient | ❌ 不序列化 |
| static | ❌ 不序列化(属于类,不属于对象) |
writeObject / readObjectprivate void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
oos.writeObject(password); // 手动序列化
}
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject();
password = (String) ois.readObject();
}
✅ 用于加密、校验、兼容旧数据
protected Object readResolve() {
return INSTANCE;
}
防止反序列化破坏单例。
public interface Externalizable extends Serializable {
void writeExternal(ObjectOutput out);
void readExternal(ObjectInput in);
}
特点:
❌ 安全问题(反序列化漏洞)
❌ 性能较差
❌ 字节流不跨语言
❌ 版本兼容性差
因此:
Java 序列化通过
Serializable标记接口,由ObjectOutputStream / ObjectInputStream在 JVM 内部将对象转换为字节流并恢复,核心依赖serialVersionUID和对象图递归处理,但因其安全性和性能问题,实际生产中应谨慎使用。
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。