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方法。