序列化与反序列化概念
- 序列化:将Java对象转换为字节序列的过程。这个字节序列可以被保存到文件、数据库,或者通过网络进行传输。这样做的目的是为了在不同环境或时间下,能够恢复对象的状态。例如,将一个包含用户信息的Java对象转化为字节流后存储到文件中。
- 反序列化:与序列化相反,是将字节序列重新恢复为Java对象的过程。当需要使用之前保存或传输过来的对象时,就进行反序列化操作。比如从文件中读取字节流并恢复成原来的用户信息对象。
应用场景
- 对象持久化:将对象保存到文件或数据库中,以便后续使用。例如,游戏中的角色信息,在玩家退出游戏时将角色对象序列化保存到文件,下次玩家登录时再反序列化读取。
- 网络传输:在分布式系统中,不同节点间传递对象时需要序列化,例如Java RMI(远程方法调用)中,客户端与服务器端传递对象参数和返回值就需要序列化与反序列化。
实现Java序列化的操作
- 实现Serializable接口:让需要序列化的类实现
java.io.Serializable
接口,该接口是一个标记接口,没有任何方法。例如:
import java.io.Serializable;
public class User implements Serializable {
private String name;
private int age;
// 构造函数、getter和setter方法省略
}
- 处理静态和瞬态字段:
- 静态字段:静态字段属于类而不是对象实例,不会被序列化。因为静态字段在类加载时初始化,不是对象状态的一部分。
- 瞬态字段:使用
transient
关键字修饰的字段不会被序列化。比如一个包含密码的字段,不想在序列化对象时保存密码,就可以将其声明为transient
。例如:
import java.io.Serializable;
public class User implements Serializable {
private String name;
private transient String password;
// 构造函数、getter和setter方法省略
}
- 自定义序列化和反序列化(可选):如果默认的序列化机制不能满足需求,可以自定义序列化和反序列化方法。通过在类中添加
writeObject
和readObject
方法来实现。例如:
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class CustomSerializableClass implements Serializable {
private int value;
private void writeObject(ObjectOutputStream out) throws IOException {
// 自定义序列化逻辑,例如对值进行加密后写入
int encryptedValue = value * 2;
out.writeInt(encryptedValue);
}
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
// 自定义反序列化逻辑,例如对值进行解密后读取
int encryptedValue = in.readInt();
value = encryptedValue / 2;
}
}