Java 中的序列化和反序列化是什么?

2024-08-25 09:00:08 153
Java 中的 序列化 和 反序列化 是将对象转换为字节流和将字节流恢复为对象的过程。这两个过程通常用于对象的持久化存储、网络传输、远程方法调用等场景。

序列化(Serialization)

序列化是将 Java 对象的状态转换为字节流的过程。序列化后的字节流可以保存到文件、数据库,或通过网络传输。

  • 主要用途

    • 将对象的状态保存到文件中(持久化)。
    • 通过网络传输对象的数据。
    • 在分布式系统中传递对象。
  • 如何实现: 对象要实现序列化,必须实现 java.io.Serializable 接口,这是一个标记接口(没有任何方法)。

示例

import java.io.*;

class Person implements Serializable { // 实现 Serializable 接口
    private static final long serialVersionUID = 1L;
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);

        // 序列化
        try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("person.ser"))) {
            out.writeObject(person);
            System.out.println("Object serialized");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,Person 对象被序列化并保存到文件 person.ser 中。

反序列化(Deserialization)

反序列化是将字节流恢复为 Java 对象的过程。反序列化后的对象恢复了之前保存的状态。

  • 主要用途
    • 从文件、数据库或网络中读取保存的对象数据。
    • 在远程调用中传递对象并恢复它们的状态。

示例

import java.io.*;

public class Main {
    public static void main(String[] args) {
        // 反序列化
        try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("person.ser"))) {
            Person person = (Person) in.readObject();
            System.out.println("Object deserialized");
            System.out.println("Name: " + person.name);
            System.out.println("Age: " + person.age);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

在这个示例中,Person 对象被反序列化,并恢复了之前保存的状态,输出对象的属性值。

注意事项

  1. serialVersionUID: 每个可序列化的类都隐式或显式地定义了一个 serialVersionUID。它用于验证在反序列化期间,发送者和接收者的类版本是否兼容。如果没有显式定义,编译器会自动生成,但建议手动定义以避免不同版本间的冲突。

    private static final long serialVersionUID = 1L;
    
  2. transient 关键字: 被 transient 修饰的字段不会被序列化。这对于那些敏感信息或不需要持久化的字段非常有用。

    示例

    class Person implements Serializable {
        private static final long serialVersionUID = 1L;
        String name;
        transient int age; // age 字段不会被序列化
    }
    
  3. 静态字段: 静态字段属于类而不属于对象,因此不会被序列化。

总结

  • 序列化 是将对象转换为字节流,用于存储或传输。
  • 反序列化 是将字节流恢复为对象,用于恢复对象状态。

序列化和反序列化在网络通信、持久化和分布式系统中非常重要,使得对象的状态可以被保存和传递。