java序列化Serializable和Externalizable

本文深入探讨了Java中Serializable与Externalizable的区别,包括它们如何处理类的构造方法及transient关键字的作用。此外,还讨论了特殊情况下单例和类型安全枚举的序列化处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Serializable是二进制位为基础保存的,可以没有任何构造方法。
Externalizable必须要手动提供一个public no-arg构造方法,否则会报错!
transient表示变量不被序列化,但是如果一个类实现Externalizable在writeObject()仍然把transient变量序列了,是可以成功的。这就失去了transient的意义!

实现Serializable也可以自定义序列化。
要有
private void writeObject(ObjectOutputStream stream) throws IOException;

private void readObject(ObjectInputStream stream)throws IOException, ClassNotFoundException

这两个方法,其中这两个方法分别是在ObjectOutputStream和ObjectInputStream中被调用,且是同名方法,在ObjectOutputStream和ObjectInputStream中还有defaultWriteObject和defaultReadObject两个方法用于对非transient变量的序列化与反序列化。

还有一种特殊的情况:序列化单例和类型安全的枚举。

在jdk5.0以前,Enum还未出现,这时一个类中会有私有构造方法来创建多个枚举值,如下

public class Orientation implements Serializable{
private int value ;
private Orientation(int i){
value = i;
}

public static final Orientation HORIZONTAL = new Orientation(1);
public static final Orignetation VERTICAL = new Orientation(2);
}

构造器是私有的,那么在这个类外就不可能会出现除HORIZONTAL和 VERTICAL的其它枚举值,因此可以用==来进行比较 ,但是在序列化和反序列化(即使构造器是私有的也可以反序列化),那么反序列化后的value和原先的HORIZONTAL和VERTICAL不能再用==比较了,因此这里就会有问题。
这时就需要再用一个方法 protected Object readResolve() throws ObjectStreamException{
if(value == 1){
return Orientation.HORIZONTAL;
}
if(value == 2){
return Orientation.VERTICAL;
}
return null;// this should not happen
}

在readObject()后面调用,将反序列化后的对象用另一个对象替换。还有一个writeReplace()方法是在writeObject()前调用,将一个对象替换成另一个对象进行序列化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值