在 Java 中,序列化 (Serialization) 和反序列化 (Deserialization) 是将对象的状态转换为字节流的过程,以便可以将对象存储到文件中或通过网络传输。这两个过程是相互逆的过程。
序列化 (Serialization)
序列化是将 Java 对象转换为字节流的过程。这通常用于以下场景:
- 持久化:将对象的状态保存到磁盘上,以便以后可以恢复。
- 网络传输:将对象的状态通过网络发送给另一台计算机。
如何序列化
要使一个对象可以被序列化,需要满足以下条件:
- 实现
Serializable接口:要序列化的类需要实现Serializable接口。这是一个标记接口,不包含任何方法,但表明该类可以被序列化。 - 使用
ObjectOutputStream:使用java.io.ObjectOutputStream类将对象写入到输出流中。
示例代码
import java.io.*;
class Person implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and Setters...
}
public class SerializationExample {
public static void main(String[] args) {
try {
// 创建一个对象
Person person = new Person("Alice", 30);
// 创建一个文件输出流
FileOutputStream fileOut = new FileOutputStream("person.ser");
ObjectOutputStream out = new ObjectOutputStream(fileOut);
// 将对象写入输出流
out.writeObject(person);
// 关闭输出流
out.close();
fileOut.close();
System.out.printf("Serialized data is saved in person.ser");
} catch (IOException i) {
i.printStackTrace();
}
}
}
反序列化 (Deserialization)
反序列化是将字节流还原为 Java 对象的过程。这通常用于从文件中读取对象或从网络接收对象。
如何反序列化
要反序列化一个对象,需要使用 java.io.ObjectInputStream 类从输入流中读取对象。
示例代码
import java.io.*;
public class DeserializationExample {
public static void main(String[] args) {
try {
// 创建一个文件输入流
FileInputStream fileIn = new FileInputStream("person.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
// 从输入流中读取对象
Person deserializedPerson = (Person) in.readObject();
// 关闭输入流
in.close();
fileIn.close();
System.out.println("Deserialized Person...");
System.out.println("Name: " + deserializedPerson.getName());
System.out.println("Age: " + deserializedPerson.getAge());
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
注意事项
- 版本兼容性:序列化过程中,每个可序列化的类都应该有一个唯一的
serialVersionUID,以确保版本兼容性。 - 私有构造函数:如果序列化的类有私有构造函数,需要提供一个无参的公共构造函数,因为反序列化过程中会调用此类构造函数。
- 暂不序列化的字段:可以使用
transient关键字声明不想序列化的字段。 - 自定义序列化:可以通过实现
writeObject和readObject方法来自定义序列化和反序列化的过程。
总结
序列化和反序列化是 Java 中非常重要的概念,它们使得对象的状态可以被持久化或在网络中传输。通过实现 Serializable 接口并使用 ObjectOutputStream 和 ObjectInputStream 类,可以轻松地实现对象的序列化和反序列化。这些技术在开发分布式系统、远程服务调用和持久化存储等领域非常有用。