返回

Java的序列化:深入浅出持久化与编码规则

后端

Java的序列化是一个强大的机制,它允许您将对象写入磁盘或将其转换为字节数组,以便您可以将其存储在数据库中或通过网络发送。此过程称为序列化。

要序列化对象,您需要做的就是实现 Serializable 接口。这会将一个名为 writeObject() 的方法添加到您的类中,该方法将对象的当前状态写入到 ObjectOutputStream。

要反序列化对象,您需要做的就是使用 ObjectInputStream 从磁盘或网络读取字节数组,然后调用 readObject() 方法。这将创建一个新对象,其状态与写入磁盘或网络的对象相同。

序列化是一个非常有用的工具,它可以用于许多不同的目的,包括:

  • 将对象存储在数据库中
  • 通过网络发送对象
  • 将对象保存在文件中以供以后使用
  • 创建对象的副本

Java 序列化的编码规则

Java 序列化的编码规则指定了对象如何转换为字节数组。这些规则非常复杂,但这里有一些要点:

  • 对象的类名是第一个被序列化的信息。
  • 对象的字段是按照声明顺序序列化的。
  • 对于每个字段,其类型是第一个被序列化的信息。
  • 如果字段是基本类型,则该值是下一个被序列化的信息。
  • 如果字段是对象,则对象的类名是下一个被序列化的信息。
  • 该过程会递归地重复,直到所有字段都被序列化。

序列化的好处

  • 持久性: 序列化允许您将对象存储在磁盘上,以便以后可以加载它们。这对于存储用户数据、应用程序设置和其他类型的持久数据非常有用。
  • 网络传输: 序列化允许您通过网络发送对象。这对于在分布式系统中发送消息或在客户端和服务器之间发送数据非常有用。
  • 对象复制: 序列化允许您创建对象的副本。这对于创建对象的多个副本以供同时使用非常有用。

序列化的局限性

  • 安全性: 序列化不提供任何安全性。这意味着任何人都可以反序列化您序列化的对象,即使他们不知道该对象的类型。
  • 性能: 序列化和反序列化对象可能会很慢。这是因为 Java 序列化是一个非常复杂的过程。
  • 兼容性: 序列化的格式可能会随着 Java 版本的变化而改变。这意味着您可能无法反序列化使用较旧版本的 Java 序列化的对象。

Java 中的序列化示例

以下是如何在 Java 中序列化对象的示例:

import java.io.*;

public class Person implements Serializable {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

        try {
            FileOutputStream fileOut = new FileOutputStream("person.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(person);
            out.close();
            fileOut.close();

            FileInputStream fileIn = new FileInputStream("person.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            Person newPerson = (Person) in.readObject();
            in.close();
            fileIn.close();

            System.out.println(newPerson.getName());
            System.out.println(newPerson.getAge());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

此示例创建一个名为 Person 的类,该类实现了 Serializable 接口。此类具有两个字段:name 和 age。main() 方法创建一个 Person 对象,然后将其序列化到磁盘。接下来,它反序列化该对象并打印其名称和年龄。