10.6.6 使用Externalizable接口

Java类只需要简单地实现标记接口Serializable就可以使用Java平台提供的默认序列化机制。如果希望进行自定义的序列化处理,那么可以在Java类中添加writeObject方法和readObject方法。虽然可以进行自定义,但是完整的序列化过程仍然是由Java平台来控制的,无法修改序列化之后的二进制格式。如果希望对序列化的过程进行完全的控制,那么可以实现java.io.Externalizable接口。Externalizable接口继承自Serializable接口,包含writeExternal和readExternal两个方法。在使用ObjectOutputStream类的对象写入Java对象时,如果该对象的Java类实现了Externalizable接口,则writeExternal方法会被调用;在使用ObjectInputStream类的对象读取Java对象时,如果实现了Externalizable接口,则readExternal方法会被调用。方法writeExternal和readExternal的作用类似于自定义序列化操作时使用的writeObject和readObject方法,只不过这两个方法是在Externalizable接口中显式声明的,更容易被开发人员所理解。代码清单10-23给出了一个实现了Externalizable接口的Java类的示例。在writeExternal方法中,使用作为参数传入的java.io.ObjectOutput类的对象来写入数据;在readExternal方法中,则使用作为参数传入的java.io.ObjectInput类的对象来读取数据并进行赋值。

代码清单10-23 Externalizable接口的使用示例


public class ExternalizableUser implements Externalizable{

private String name;

private String email;

public ExternalizableUser(){

}

public ExternalizableUser(String name, String email){

this.name=name;

this.email=email;

}

public String getName(){

return this.name;

}

public String getEmail(){

return this.email;

}

public void writeExternal(ObjectOutput out)throws IOException{

out.writeUTF(getName());

out.writeUTF(getEmail());

}

public void readExternal(ObjectInput in)throws IOException,

ClassNotFoundException{

name=in.readUTF();

email=in.readUTF();

}

}


实现Externalizable接口的Java类必须具备一个不带参数的公开构造方法。在反序列化的过程中,如果对象的Java类实现了Externalizable接口,则先调用不带参数的公开构造方法得到一个新的对象,再在此对象上调用readExternal方法。