Java 进阶之路:探索序列化和反序列化的神奇之处

65 阅读2分钟

在 Java 中,序列化 (Serialization) 和反序列化 (Deserialization) 是将对象的状态转换为字节流的过程,以便可以将对象存储到文件中或通过网络传输。这两个过程是相互逆的过程。

序列化 (Serialization)

序列化是将 Java 对象转换为字节流的过程。这通常用于以下场景:

  • 持久化:将对象的状态保存到磁盘上,以便以后可以恢复。
  • 网络传输:将对象的状态通过网络发送给另一台计算机。

如何序列化

要使一个对象可以被序列化,需要满足以下条件:

  1. 实现 Serializable 接口:要序列化的类需要实现 Serializable 接口。这是一个标记接口,不包含任何方法,但表明该类可以被序列化。
  2. 使用 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 接口并使用 ObjectOutputStreamObjectInputStream 类,可以轻松地实现对象的序列化和反序列化。这些技术在开发分布式系统、远程服务调用和持久化存储等领域非常有用。