Java外部化接口示例

时间:2020-01-09 10:35:19  来源:igfitidea点击:

当类实现Serializable接口时,对象序列化是自动的,我们只需调用writeObject()和readObject()方法进行序列化和反序列化即可。如果要通过更多控制权自定义序列化过程,则可以使用Java中的Externalizable接口。

Java中的可外部化接口

java.io.Externalizable接口扩展了Serializable接口,并添加了自己的两种方法

writeExternal(ObjectOutput out)–通过调用基本类型的writexxx方法和对象的writeObject方法将对象写入流中。这种为各个字段调用write()方法的灵活性使我们可以控制序列化过程。

readExternal(ObjectInput in)–通过调用基本类型的readxxx方法和对象的readObject方法从流中读取对象。

我们想要控制其对象序列化的任何类都应实现Externalizable接口的writeExternal和readExternal方法。

可外部化的Java示例

在示例中,我们有一个Employee类,该类实现Externalizable接口。 Employee类中有四个字段,在writeExternal()方法中,我们可以控制将这些字段中的哪些字段写入流中。在此示例中,工资字段被省略。

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class Employee implements Externalizable{
  private String name;
  private String dept;
  private int salary;
  private int age;
  // no arg constructor required
  public Employee(){}
  Employee(String name, String dept, int salary, int age){
    this.name = name;
    this.dept = dept;
    this.salary = salary;
    this.age = age;
  }

  public int getAge() {
    return age;
  }

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

  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getDept() {
    return dept;
  }
  public void setDept(String dept) {
    this.dept = dept;
  }
  public int getSalary() {
    return salary;
  }
  public void setSalary(int salary) {
    this.salary = salary;
  }

  @Override
  public void writeExternal(ObjectOutput out) throws IOException {
    System.out.println("In writeExternal method");
    out.writeObject(name);
    out.writeObject(dept);
    out.writeInt(age);		
  }

  @Override
  public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
    System.out.println("In readExternal method");
    name = (String)in.readObject();
    dept = (String)in.readObject();
    age = in.readInt();
  }
}

这是一个对Employee类对象进行序列化和反序列化的类。

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class ExternalizableDemo {
  public static void main(String[] args) {
    Employee emp = new Employee("Ryan", "IT", 7500, 34);
    final String fileName = "F:\theitroad\emp.ser";
    ObjectOutputStream outStream;
    try {
      // Serializing object
      outStream = new ObjectOutputStream(new FileOutputStream(fileName));
      outStream.writeObject(emp);
      outStream.close();
        
      // Deserializing object
      ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(fileName));
      emp = (Employee)inputStream.readObject();
      inputStream.close();
      System.out.println("Name: " + emp.getName() + " Dept: " 
        + emp.getDept() + " Salary: " + emp.getSalary() + " Age: " + emp.getAge());
    } catch (IOException | ClassNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
}

输出:

In writeExternal method
In readExternal method
Name: Ryan Dept: IT Salary: 0 Age: 34

有关Externalizable的一些要点

  • 在反序列化过程中重建Externalizable对象时,首先使用公共无参数构造函数创建对象实例,然后调用readExternal方法。因此,请确保实现Externalizable的类具有公共的无参数构造函数。

  • 在readExternal()方法中,应以与在writeExternal()方法中写入的顺序相同的顺序读取字段,否则将引发异常。

Java中的序列化顺序

外部化优先于序列化。测试了每个序列化的对象的Externalizable接口。如果对象支持Externalizable,则调用writeExternal方法。如果对象不支持Externalizable并且实现了Serializable,则使用ObjectOutputStream保存该对象。

重建Externalizable对象时,将使用公共的无参数构造函数创建实例,然后调用readExternal方法。可序列化的对象通过从ObjectInputStream读取来恢复。