对象序列化输入/输出流

ObjectOutputStream 类的对象用于序列化一个对象。ObjectInputStream 类的对象用于反序列化一个对象。ObjectOutputStream 类继承自 OutputStream 类。ObjectInputStream 类继承自 InputStream 类。

一个类只有实现 Serializable 或 Externalizable 接口,才能被序列化或反序列化。Serializable 接口是一个标记接口。例如,序列化一个 Book 类对象的代码如下:

import java.io.Serializable;
public class Book implements Serializable {

}

Java 负责处理从输入流中读取或者向输出流中写入 Serializable 对象的细节。

实现 Externalizable 接口能够更好地控制从输入流中读取对象和向输出流中写入对象。这是因为 Externalizable 接口继承了 Serializable 接口。Externalizable 接口的代码如下:

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.Serializable;
public interface Externalization extends Serializable {
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
    void writeExternal(ObjectOutput out) throws IOException;
}

当从输入流中读取一个对象时,需要调用 readExternal() 方法;当向输出流中写入一个对象时,需要调用 writeExternal() 方法。

Book 类实现 Externalizable 接口的代码如下:

import java.io.Externalizable;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.IOException;
public class Book implements Externalizable {
    void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
    void writeExternal(ObjectOutput out) throws IOException;
}

序列化对象

序列化一个 Book 类对象需要执行如下步骤:

  • 创建 ObjectOutputStream 类的对象,并将对象保存到 book.ser 文件中。

  • 将对象保存到 ByteArrayOutputStream 类中,并构造一个对象输出流。

  • 使用 ObjectOutputStream 类的 writeObject() 方法序列化对象。

  • 关闭对象输出流。

依据上述步骤,在 Book.java 文字中编写 Book 类。代码如下:

import java.io.Serializable;

public class Book implements Serializable {
    private String name;
    private double price;

    public Book(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String toString() {
        return "Name:" + this.name + ",price: " + this.price;
    }

}

在 BookOutTest.java 文件中编写序列化 Book 类对象的代码。代码如下:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class BookOutTest {
    public static void main(String[] args) {
        Book book1 = new Book("Java从入门到精通", 79.8);
        Book book2 = new Book("C#从入门到精通", 99.8);
        File fileObject = new File("book.ser");
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileObject))) {
            oos.writeObject(book1);
            oos.writeObject(book2);
            System.out.println(book1);
            System.out.println(book2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

执行程序后,会把对象 book1 和 book2 各自的书名和价格输出到控制台上,并且把它们各自被序列化后的对象存储在当前项目文件夹下的 book.ser 文件中。

反序列化对象

反序列化一个 Book 类对象需要执行如下步骤:

  • 创建 ObjectInputStream 类的对象,并从 book.ser 文件中读取对象。

  • 从 ByteArrayInputStream 类中读取对象,创建一个对象输入流。

  • 使用 ObjectInputStream 类的 readObject() 方法反序列化对象。

  • 关闭对象输入流。

依据上述步骤,在 Book.java 和 book.ser 都保持不变的情况下,在 BookInTest.java 文件中编写反序列化 Book 类对象的代码。代码如下:

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class BookInTest {
    public static void main(String[] args) {
        File fileObject = new File("book.ser");
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileObject))) {
            Book book1 = (Book)ois.readObject();
            Book book2 = (Book)ois.readObject();
            System.out.println(book1);
            System.out.println(book2);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

执行程序后,会发现被输出到控制台上的结果就是 book.ser 文件存储的序列化对象。