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



 




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章