JDK8 API——java.io.serializable

java.io

Interface Serializable

子接口:

AdapterActivatorAttributeAttributeAttributesBindingIteratorCertPathValidatorException.ReasonClientRequestInfo

ClientRequestInterceptorCodecCodecFactoryControlCurrentCurrentCurrentCustomValueDataInputStream

DataOutputStreamDescriptorDHPrivateKeyDHPublicKeyDocAttributeDomainManagerDSAPrivateKeyDSAPublicKey

DynAnyDynAnyFactoryDynArrayDynEnumDynFixedDynSequenceDynStructDynUnionDynValueDynValueBoxDynValueComm

onECPrivateKeyECPublicKeyExtendedRequestExtendedResponseExternalizableIdAssignmentPolicyIDLEntity

IDLTypeIdUniquenessPolicyImplicitActivationPolicyInterceptorIORInfoIORInterceptorIORInterceptor_3_0

IRObjectKeyLifespanPolicyNameNamingContextNamingContextExtNotificationFilterObjectReferenceFactory

ObjectReferenceTemplateORBInitializerORBInitInfoPBEKeyPOAPOAManagerPolicyPolicyFactoryPrintJobAttribute,

 PrintRequestAttributePrintServiceAttributePrivateKeyPublicKeyQueryExpRelationTypeRemoteRefRequestInfo

RequestProcessingPolicyRSAMultiPrimePrivateCrtKeyRSAPrivateCrtKeyRSAPrivateKeyRSAPublicKeyRunTimeSecretKey,

 ServantActivatorServantLocatorServantManagerServantRetentionPolicyServerRefServerRequestInfo

ServerRequestInterceptorStreamableValueSupportedValuesAttributeThreadPolicyUnsolicitedNotificationValueBase

ValueExp

一个类的序列化是由类实现java.io.serializable接口启用。类没有实现这个接口不会有任何状态序列化或反序列化。所有子类型的序列化类本身是可序列化的。序列化接口没有任何方法或字段且只能识别可序列化的语义。

为了允许子类型的非序列化的类进行序列化,子类型可能承担了保存和恢复的超类型的public、protected、package域的状态的责任。子类型可能承担这个责任只有该超类有一个可访问的无参数构造函数来初始化该类的状态。声明一个没有实例的可序列化类是错误的,这个错误将在运行时被检测到。

在反序列化期间,非序列化的类的字段将使用public或protected类的无参数构造函数进行初始化。一个无参构造器必须是可序列化的子类可访问的。可序列化子类的字段将从流恢复。

当遍历一个图,一个对象时可能会遇到图或对象不支持序列化的接口。在这种情况下NotSerializableException异常将抛出,并认为这个类是不可序列化的类。

在序列化和反序列化过程中需要特殊处理的那些类,必须实现有如下具体特征的特殊方法:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData()
     throws ObjectStreamException;writeObject

writeObject方法负责修改其特定的类的对象的状态,相应的readObject()方法可以恢复对象的状态。保存对象的字段的默认机制可以通过调用out.defaultwriteobject实现。该方法不需要担心自己的状态属于其超类或者子类。通过writeObject方法或使用DataOutput.支持的原始数据类型的方法把个体域写到ObjectOutputStream(对象输出流)来保存状态

readObject方法负责从流中读取和恢复类的字段。它可以调用in.defaultreadobject以使用恢复对象的非静态和非瞬态字段的默认机制。defaultReadObject方法使用流中的信息来分配保存在流中对象相对应的当前对象的字段名的对象的字段。这种情况下,当类需要添加新字段时,该方法不需要担心自己属于其超类或子类的状态。通过writeObject方法或使用DataOutput.支持的原始数据类型的方法把个体域写到ObjectOutputStream(对象输出流)来保存状态

readObjectNoData方法负责初始化对象的状态的特定类型当序列化流不列出给定反序列化类的父类的对象。可能存在下面的情况,发送方与接受方使用不同译本的反序列化实例的类,接收器继承的类与发送者的类版本不一致,或者序列化流已被篡改;因此,readObjectNoData用于初始化“不一致的”或不完整的资源流的反序列化对象

可序列化的类需要指定一个非正式的被使用的对象,当把一个对象写入到流时,需要实现具有如下特征的方法:

ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
序列化使用了writeReplace方法,如果该方法存在,它必须是可访问的在被序列化的对象的类中定义的方法。因此,该方法的访问权限可以是private、protected和package-private。子类访问该方法遵循java访问规则。

类需要指定一个替换的类,当该类的一个实例从流中读数据时需要实现具有如下特征的方法:

 ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
这个 readResolve 方法遵循与writeReplace方法相同的调用规则和访问规则。

序列化运行过程联合了每个可序列化类的一个版本号(即serialVersionUID), serialVersionUID用于在反序列化期间判别发送方和接收方序列化的对象是否与加载类的序列化对象一致。如果接收方加载的可序列化类的对象的serialVersionUID与发送方的不一致,则反序列化将导致InvalidClassException异常。一个可序列化的类可以明确声明自己的serialVersionUID通过声明一个名为"serialVersionUID"的字段,但这个字段必须是static、 final和long类型:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

如果一个序列化的类没有显式声明serialVersionUID,则序列化运行时将基于该类的类的各个方面推测一个默认的serialVersionUID值,作为java对象序列化规范描述(TM)。然而,还是强烈建议所有可序列化的类都明确的声明serialVersionUID值,因为默认serialVersionUID的估值非常依赖于类的细节,可能由于编译器实现的不同而有不一样的值,从而导致在反序列化期间意外invalidClassExceptions。因此,为了保证在不同的Java编译器实现中有一致的serialVersionUID值,可序列化类必须声明一个明确的serialVersionUID值。它也强烈建议尽可能显式的声明serialVersionUID时使用private修饰符,因为这样的声明只适用于当前类—— serialVersionUID字段不能作为继承的成员。数组类不能声明一个明确的serialVersionUID,所以他们总是有默认的估计值,但因为要求匹配serialVersionUID值,所以放弃了数组类声明serialVersionUID


Since:
JDK1.1
See Also:
ObjectOutputStreamObjectInputStreamObjectOutputObjectInputExternalizable



 




  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值