java序列化的使用很简单的用法就是,在类定义时实现java.io.serializable即可。扩展这个接口不需要实现它的任何方法,Java会自动序列化。需要注意的,被标为transient和static的属性是不会被java自动序列化的。
在面对比较复杂的对象时,比如存在双向链接关系的对象时,如果实现该接口,java在序列化时会栈溢出,如果对象比较大,会出现堆溢出。那么这时候就需要我们自己动手写一个序列化的方法。
第一种自定义序列化方式:
1、类定义扩展java.io.serializable接口;
2、类中实现方法如下:
private void writeObject(java.io.ObjectOutputStream out) throws IOException{
out.defaultWriteObject(); // java序列化默认实现,不包含transient和static的属性
//TODO : transient和static的序列化
}
private void readObject(java.io.ObjectInputStream in) throws ClassNotFoundException, IOException{
in.defaultReadObject();
//TODO:和writeObject的顺序相同的读
}
第二种实现方式:
1、类定义扩展java.io.Externalizable接口;
2、类中实现方法如下:
@Override
public void readExternal(ObjectInput in) throws IOException,
ClassNotFoundException {
//TODO:和writeExternal相同的顺序
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
//TODO:具体序列化的思路
}
在第一种方式中,需要注意方法是private的,java是通过反射的方式来找到readObject和writeObject方法完成序列化和反序列化过程的。而且,第一种方式中,方法的实现不是必须的,第二种方式是必须要实现方法的。
另外的一点儿序列化的经验是:如果需要序列化的内容过大,而且重复的内容较多时,可以新建一个HashMap,对可能出现重复的内容映射为比较容易存放而且占用空间较小的整形、字节、字符等;尽量多使用writeInt、writeByte来替代writeUTF、writeObject;序列化的代码为了简化多写几行,序列化的结果文件大小、(反)序列化的时间可能缩短很多倍。