Java中的序列化与反序列化机制详解
字数 698 2025-11-05 23:47:54
Java中的序列化与反序列化机制详解
一、序列化的基本概念
序列化是将Java对象转换为字节序列的过程,反序列化则是将字节序列恢复为Java对象的过程。这个机制使得对象可以脱离程序独立存在,便于网络传输或持久化存储。
二、序列化的实现方式
- 实现Serializable接口(标记接口)
public class User implements Serializable {
private String name;
private int age;
// 必须提供无参构造器
public User() {}
// getter/setter方法
}
- 实现Externalizable接口(需要重写方法)
public class User implements Externalizable {
private String name;
private int age;
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name); // 自定义序列化逻辑
}
@Override
public void readExternal(ObjectInput in) throws IOException {
this.name = in.readUTF(); // 自定义反序列化逻辑
}
}
三、序列化的具体步骤
- 创建对象输出流:
User user = new User("张三", 25);
try (ObjectOutputStream oos = new ObjectOutputStream(
new FileOutputStream("user.dat"))) {
oos.writeObject(user); // 执行序列化
}
- 序列化过程详解:
- 检查对象是否实现Serializable接口
- 通过反射获取对象的所有字段
- 递归序列化所有引用的对象
- 将对象数据转换为字节流写入输出源
四、反序列化的具体步骤
- 创建对象输入流:
try (ObjectInputStream ois = new ObjectInputStream(
new FileInputStream("user.dat"))) {
User user = (User) ois.readObject(); // 执行反序列化
}
- 反序列化过程详解:
- 读取字节流并解析元数据
- 通过反射调用无参构造器创建空对象
- 递归反序列化所有字段值
- 恢复对象完整状态
五、serialVersionUID的作用
- 版本控制标识符,用于验证序列化对象的兼容性
- 显式声明的正确方式:
private static final long serialVersionUID = 1L;
- 如果没有显式声明,JVM会自动根据类结构生成,类结构变化会导致反序列化失败
六、自定义序列化策略
- 使用transient关键字忽略字段:
private transient String password; // 不会被序列化
- 重写writeObject/readObject方法:
private void writeObject(ObjectOutputStream oos)
throws IOException {
oos.defaultWriteObject(); // 默认序列化
oos.writeUTF(encrypt(password)); // 自定义处理
}
private void readObject(ObjectInputStream ois)
throws IOException, ClassNotFoundException {
ois.defaultReadObject(); // 默认反序列化
this.password = decrypt(ois.readUTF()); // 自定义处理
}
七、序列化注意事项
- 静态变量不会被序列化(属于类级别)
- 父类序列化规则:
- 父类实现Serializable:子类自动可序列化
- 父类未实现:需要有无参构造器,且父类字段不会被序列化
- 内部类序列化问题:建议使用静态内部类
八、实际应用场景
- 对象网络传输(RPC调用)
- 对象持久化存储
- 分布式缓存存储
- 深拷贝实现方案
通过理解这些细节,可以避免常见的序列化陷阱,并能够根据业务需求灵活定制序列化策略。