在 Java 中,序列化和反序列化是用于将对象的状态转换为字节流(序列化),以及从字节流恢复对象的状态(反序列化)的过程。这一机制使得对象可以通过网络传输或保存到文件系统中,并在需要时重新构建对象的原始状态。
序列化
- 定义:序列化是指将一个对象转换成字节序列的过程,这样可以方便地存储对象或者通过网络发送对象。
- 实现方式:要使一个类的对象能够被序列化,该类必须实现
java.io.Serializable
接口。这个接口是一个标记接口,不需要实现任何方法。 - 用途:
- 将对象保存到磁盘上以便将来使用。
- 在分布式系统中通过网络传输对象。
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;
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class SerializationDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person person = new Person("John", 30);
// 序列化
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
oos.writeObject(person);
}
// 反序列化
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) {
Person deserializedPerson = (Person) ois.readObject();
System.out.println(deserializedPerson);
}
}
}
反序列化
- 定义:反序列化是序列化的逆过程,指的是将字节流转换回对象的过程。
- 注意事项:
- 反序列化后的对象与原始对象具有相同的类型和数据,但它们不是同一个对象实例。
- 如果类中包含非
transient
的静态变量,则这些变量不会被序列化;即反序列化后它们会保留其默认值或最后一次显式赋值的状态。 serialVersionUID
是用来验证序列化和反序列化过程中类版本的一致性。如果接收方加载的类与发送方使用的类有不同的serialVersionUID
,则反序列化将失败。
关键点
transient
关键字:标记为transient
的字段不会被序列化。这对于那些不应该被持久化或传输的数据非常有用,如密码、敏感信息等。serialVersionUID
:建议为每个实现了Serializable
接口的类手动指定一个serialVersionUID
,以确保兼容性。如果没有显式定义,Java 运行时环境会基于类的结构自动生成一个,这可能导致不同版本之间的不兼容问题。
通过序列化和反序列化,Java 提供了一种强大的机制来处理对象的持久化和网络传输,广泛应用于分布式系统、缓存、远程方法调用等领域。理解并正确使用序列化机制对于开发高效可靠的 Java 应用程序至关重要。
THE END