Java对象序列化和反序列化(附带实例)
在 Java 中,ObjectOutputStream 类的对象用于序列化一个对象,ObjectInputStream 类的对象用于反序列化一个对象。ObjectOutputStream 类继承自 OutputStream 类,ObjectInputStream 类继承自 InputStream 类。
Java 程序中,一个类只有实现 Serializable 或 Externalizable 接口,才能被序列化或反序列化。Serializable 接口是一个标记接口。
例如,序列化一个 Book 类对象的代码如下:
实现 Externalizable 接口能够更好地控制从输入流中读取对象和向输出流中写入对象。这是因为 Externalizable 接口继承了 Serializable 接口。Externalizable 接口的代码如下:
Book 类实现 Externalizable 接口的代码如下:
依据上述步骤,在 Book.java 文字中编写 Book 类。代码如下:
在 BookOutTest.java 文件中编写序列化 Book 类对象的代码。代码如下:
依据上述步骤,在 Book.java 和 book.ser 都保持不变的情况下,在 BookInTest.java 文件中编写反序列化 Book 类对象的代码。代码如下:
Java 程序中,一个类只有实现 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 Externalizable 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.IOException; import java.io.ObjectInput; import java.io.ObjectOutput; public class Book implements Externalizable { public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { } public void writeExternal(ObjectOutput out) throws IOException { } }
Java序列化对象
序列化一个 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; } @Override 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基础教程", 49.9); Book book2 = new Book("C语言入门教程", 49.8); File fileObject = new File("book.ser"); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileObject))) { os.writeObject(book1); os.writeObject(book2); System.out.println(book1); System.out.println(book2); } catch (IOException e) { e.printStackTrace(); } } }执行程序后,会把对象 book1 和 book2 各自的书名和价格输出到控制台上,并且把它们各自被序列化后的对象存储在当前项目文件夹下的 book.ser 文件中。
Java反序列化对象
反序列化一个 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 (Exception e){ e.printStackTrace(); } } }执行程序后,会发现被输出到控制台上的结果就是 book.ser 文件存储的序列化对象。