Java外部化接口示例
当类实现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读取来恢复。

