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读取来恢复。