JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。Externalizable继承于Serializable,当使用该接口时,序列化的细节需要由程序员去完成。
测试代码:
class="java">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("读取持久化对象");
	}
	@Override
	public void readExternal(ObjectInput arg0) throws IOException,
			ClassNotFoundException {
		// TODO Auto-generated method stub
	}
	@Override
	public 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 constructor name==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("读取持久化对象");
	}
	*/
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(fClub);
        out.writeInt(age);
        System.out.println("自定义序列化过程");
	} 
	
	@Override
	public 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