对象序列化输入/输出流
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 文件存储的序列化对象。