有关Java序列化(三)——使用Externalizable
import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectInputStream;import java.io.ObjectOutput;import java.io.ObjectOutputStream;public class Person implements Externalizable {private static final long serialVersionUID = -842029427676826563L;public static String name;private int age;private transient int workDay = 5;private String fClub;public Person() { System.out.println("none-arg constructor"); }public Person(int age, String fClub) { this.age = age; this.fClub = fClub; }public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getWorkDay() {return workDay;}public void setWorkDay(int workDay) {this.workDay = workDay;}public String getfClub() {return fClub;}public void setfClub(String fClub) {this.fClub = fClub;}private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();//执行默认的序列化机制out.writeInt(workDay);System.out.println("正在进行序列持久化");}private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {in.defaultReadObject();workDay = in.readInt();System.out.println("读取持久化对象");}@Overridepublic void readExternal(ObjectInput arg0) throws IOException,ClassNotFoundException {// TODO Auto-generated method stub}@Overridepublic void writeExternal(ObjectOutput arg0) throws IOException {// TODO Auto-generated method stub} }
?主测试类代码:
import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;public class Hello {public static void main(String[] args) {Person person = new Person(26, "Juventus");person.setWorkDay(7);try {FileOutputStream fs = new FileOutputStream("foo.ser");ObjectOutputStream os = new ObjectOutputStream(fs);os.writeObject(person);os.close();Person.name = "Alex";FileInputStream in = new FileInputStream("foo.ser");ObjectInputStream s = new ObjectInputStream(in);Person p = (Person) s.readObject();System.out.println("name==" + Person.name + " age==" + p.getAge()+ " workDay==" + p.getWorkDay() + " fClub==" + p.getfClub());} catch (Exception e) {e.printStackTrace();}}}?程序输出为:
none-arg constructorname==Alex age==0 workDay==5 fClub==null
?
?????? 从结果来看,writeObject和readObject没再被执行,Person p = (Person) s.readObject()读取持久化类的时候调用了Person的无参构造函数。同时发现,foo.ser文件里只有类的类型声明,没有任何实例变量,Person对象中任何一个字段都没有被序列化,所以打印结果里面,age为0,fClub为null,而workDay为初始值5。
??????? 如上所示的代码,由于writeExternal()与readExternal()方法未作任何处理,那么该序列化行为将不会保存/读取任何一个字段。
更改Person类:
import java.io.Externalizable;import java.io.IOException;import java.io.ObjectInput;import java.io.ObjectInputStream;import java.io.ObjectOutput;import java.io.ObjectOutputStream;public class Person implements Externalizable {private static final long serialVersionUID = -842029427676826563L;public static String name;private int age;private transient int workDay = 5;private String fClub;public Person() { System.out.println("none-arg constructor"); }public Person(int age, String fClub) { this.age = age; this.fClub = fClub; }public int getAge() {return age;}public void setAge(int age) {this.age = age;}public int getWorkDay() {return workDay;}public void setWorkDay(int workDay) {this.workDay = workDay;}public String getfClub() {return fClub;}public void setfClub(String fClub) {this.fClub = fClub;}/*//writeObject和readObject不再被执行private void writeObject(ObjectOutputStream out) throws IOException {out.defaultWriteObject();//执行默认的序列化机制out.writeInt(workDay);System.out.println("正在进行序列持久化");}private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {in.defaultReadObject();workDay = in.readInt();System.out.println("读取持久化对象");}*/@Overridepublic void writeExternal(ObjectOutput out) throws IOException {out.writeObject(fClub); out.writeInt(age); System.out.println("自定义序列化过程");} @Overridepublic void readExternal(ObjectInput in) throws IOException,ClassNotFoundException {fClub = (String) in.readObject(); age = in.readInt(); System.out.println("自定义反序列化");}}?主测试程序的输出结果为:
自定义序列化过程none-arg constructor自定义反序列化name==Alex age==26 workDay==5 fClub==Juventus
????????使用Externalizable进行序列化,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。这就是为什么输出结果中会显示调动了无参构造器。由于这个原因,实现Externalizable接口的类必须要提供一个无参的构造器,且它的访问权限为public。
?
参考:
http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html
