实现 java.io.Serializable接口的作用

实现java.io.Serializable接口的类启用了类的可序列化。未实现此接口的类将不会将其任何状态序列化或反序列化。可序列化类的所有子类本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

为了允许序列化非可序列化类的子类型,子类型可能负责保存和恢复超类型的public,protected和(如果可访问)包字段的状态。只有当扩展的类具有可访问的no-arg构造函数初始化类的状态时,子类型才可以承担此责任。声明类Serializable是错误的,如果不是这样的话。将在运行时检测到错误。

在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。必须可以访问可序列化的子类*的无参数构造函数。可序列化子类的字段将从流中恢复。

遍历图形时,可能会遇到不支持Serializable接口的对象。在这种情况下,将抛出 NotSerializableException,并将标识非可序列化对象的类。

一、在序列化和反序列化过程中需要特殊处理的类必须使用这些精确的签名实现特殊方法:
 1、private void writeObject(java.io.ObjectOutputStream out) throws IOException;
 2、private void readObject(java.io.ObjectInputStream in)  throws IOException, ClassNotFoundException;
 3、private void readObjectNoData() throws ObjectStreamException;

1、writeObject方法负责为其特定类编写对象的状态,以便相应的 readObject方法可以恢复它。保存Object的字段的默认机制可以通过调用 out.defaultWriteObject来调用。该方法不需要将本身与属于其超类或子类的状态联系起来。 通过使用writeObject方法将单个字段写入ObjectOutputStream或使用DataOutput支持的原始数据类型的方法来保存状态。
2、readObject方法负责从流中读取和恢复类字段。它可以调用in.defaultReadObject来调用恢复对象的非静态和非瞬态字段的默认机制。 defaultReadObject方法使用流中的信息来分配流中保存的对象的字段,并在当前对象中使用相应命名的字段。当类已经发展为添加新字段时,它处理大小写。该方法不需要关注属于其超类或子类的状态。 通过使用writeObject方法将单个字段写入 ObjectOutputStream或使用DataOutput支持的原始数据类型的方法来保存状态。
3、readObjectNoData方法负责初始化的状态如果序列化流不将给定类作为对象的超类列出反序列化。在接收方使用反序列化实例类的版本与发送的版本不同参与方和接收者的版本扩展的类不是发件人的版本。如果序列化流具有已被篡改;因此,readObjectNoData对于初始化非常有用尽管存在“敌对”或不完整的源,但正确反序列化对象流。

二、需要将可选对象指定为在将对象写入流时使用应实现此具有准确签名的特殊方法:
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
如果方法存在,并且可以从中定义的方法访问正在序列化的对象的类。因此,该方法可以是私有的,受保护并打包专用访问。子类访问此方法遵循Java可访问性规则。

三、当它的一个实例从流中读取时,应使用准确签名。
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
此readResolve方法遵循与writeReplace相同的调用规则和可访问性规则。

四、序列化运行时与每个可序列化类A版本关联编号,称为serialversionID,在反序列化到验证序列化对象的发送方和接收方是否已加载与序列化兼容的对象的类。如果接收器已为具有不同比相应发送方类serialversionID,则反序列化将导致invalidClassException。可序列化类可以通过声明一个名为“serialversionuid”的字段,该字段必须是静态的,并且属于类型long
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
如果可序列化类没有显式声明serialversionID,则序列化运行时将计算默认的serialversionuid值对于基于类的各个方面的类,如Java(TM)对象序列化规范。但是,它是强的建议所有可序列化类显式声明serialversionuid值,因为默认的serialversionuid计算为对类细节高度敏感,根据编译器的不同而有所不同实现,因此可能导致意外在反序列化期间,invalidClassExceptions。因此,到在不同Java编译器之间保证一致的序列化版本值实现,可序列化类必须声明显式serialversionID值。此外,强烈建议serialversionuid声明使用private,因为此类声明仅适用于立即声明的class--serialversionID字段作为继承成员不有用。数组类不能声明显式的serialversionID,因此它们总是默认的计算值,但需要匹配对于数组类,放弃serialversionID值。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值