- 既知のすべてのサブインタフェース:
Attribute
,Attribute
,Attributes
,CertPathValidatorException.Reason
,Connector.Argument
,Connector.BooleanArgument
,Connector.IntegerArgument
,Connector.SelectedArgument
,Connector.StringArgument
,Control
,Descriptor
,DHPrivateKey
,DHPublicKey
,DocAttribute
,DSAPrivateKey
,DSAPublicKey
,ECPrivateKey
,ECPublicKey
,EdECPrivateKey
,EdECPublicKey
,ExtendedRequest
,ExtendedResponse
,Externalizable
,Key
,Name
,NotificationFilter
,PBEKey
,PrintJobAttribute
,PrintRequestAttribute
,PrintServiceAttribute
,PrivateKey
,PublicKey
,QueryExp
,RelationType
,RemoteRef
,RSAMultiPrimePrivateCrtKey
,RSAPrivateCrtKey
,RSAPrivateKey
,RSAPublicKey
,SecretKey
,ServerRef
,SupportedValuesAttribute
,UnsolicitedNotification
,ValueExp
,XECPrivateKey
,XECPublicKey
警告: 信頼できないデータの直列化復元は、本質的に危険であり、回避する必要があります。 「Java SEに対するセキュア・コーディングのガイドライン」の"直列化および直列化復元"セクションに従って、信頼できないデータを慎重に検証する必要があります。 「直列化フィルタリング」では、シリアル・フィルタの使いやすさに関するベスト・プラクティスについて説明します。
このインタフェースを実装していないクラスでは、その状態が直列化または直列化復元されることはありません。 直列化可能クラスのサブタイプは、すべてそれ自体が直列化可能です。 直列化インタフェースはメソッドまたはフィールドがなく、直列化可能であるという意味を識別する機能だけを備えています。直列化可能でないクラスのサブタイプを直列化および直列化復元できます。 直列化時に、直列化可能でないスーパークラスのフィールドにデータは書き込まれません。 直列化復元中、直列化可能でないスーパークラスのフィールドは、最初の(bottommost)直列化可能でないスーパークラスの引数なしコンストラクタを使用して初期化されます。 このコンストラクタは、直列化復元されるサブクラスからアクセスできる必要があります。 そうでない場合は、Serializableクラスを宣言するとエラーになり、実行時にエラーが検出されます。 直列化可能サブタイプは、直列化可能でないスーパータイプpublic、protected、および(アクセス可能な場合) package-accessフィールドの状態を保存およびリストアする責任を負うことがあります。 直列化可能クラスと非直列化可能クラスの処理を含む直列化復元プロセスの詳細な仕様については、「Javaオブジェクト直列化仕様」のセクション3.1を参照してください。
グラフの巡回中に、直列化可能インタフェースをサポートしていないオブジェクトに遭遇することがあります。 この場合は、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メソッドは、その特定のクラスのオブジェクトの状態を書き込んで、対応するreadObjectメソッドがオブジェクトの状態を復元できるようにする役割を担います。 out.defaultWriteObjectを呼び出せば、オブジェクトのフィールドを保存するためのデフォルトのメカニズムを呼び出すことができます。 このメソッドは、そのスーパー・クラスやサブクラスに属する状態に関与する必要はありません。 状態を保存するには、writeObjectメソッドを使って個々のフィールドをObjectOutputStreamに書き込むか、またはDataOutputがサポートするプリミティブ・データ型用のメソッドを使用します。
readObjectメソッドは、ストリームからの読み込みとクラス・フィールドの復元を行う役割を担います。 このメソッドは、in.defaultReadObjectメソッドを呼び出して、オブジェクトの非staticフィールドおよび非transientフィールドを復元するためのデフォルトのメカニズムを呼び出すことができます。 defaultReadObjectメソッドは、ストリームの情報を使用して、現在のオブジェクト内で対応するように指定されたフィールドとともに、ストリームに保存されているオブジェクトのフィールドを割り当てます。 これで、新しいフィールドを追加できるようにクラスが拡張されるケースが処理されます。 このメソッドは、そのスーパー・クラスやサブクラスに属する状態に関与する必要はありません。 状態を復元するには、個々のフィールドについてObjectInputStreamからデータを読み込み、オブジェクトの適切なフィールドへの割り当てを行います。 プリミティブ・データ型の読込みは、DataInputによってサポートされます。
readObjectNoDataメソッドは、あるクラスが直列化復元されるオブジェクトのスーパー・クラスとして直列化ストリームに指定されていないときに、そのクラスについてそのオブジェクトの状態を初期化します。 これは、受取り側が送り側とは異なるバージョンの直列化復元されたインスタンスのクラスを使用し、受取り側のバージョンが送り側のバージョンによって継承されないクラスを継承する場合に発生する可能性があります。 また、直列化ストリームが改変された場合にも発生することがあります。したがって、readObjectNoDataは、「悪意のある」または不正なソース・ストリームであっても、直列化復元されたオブジェクトを正しく初期化するのに役立ちます。
ストリームにオブジェクトを書き込むときに使う代替オブジェクトを指定する必要がある直列化可能クラスでは、次のシグネチャを正確に指定して、この特別なメソッドを実装する必要があります。
ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;
このwriteReplaceメソッドが直列化によって呼び出されるのは、存在していて、しかも直列化されるオブジェクトのクラス内で定義されているメソッドからアクセス可能な場合です。 そのため、このメソッドでは、private、protected、およびpackage-privateでアクセスすることができます。 このメソッドに対するサブクラスのアクセスは、javaのアクセス可能性ルールに準拠します。
代替オブジェクトのインスタンスをストリームから読み込むときにそのオブジェクトを指定する必要のあるクラスでは、次のシグネチャを正確に指定して、この特別なメソッドを実装する必要があります。
ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;
このreadResolveメソッドは、writeReplaceと同じ呼び出しルールとアクセス可能性ルールに準拠します。
列挙型はすべて直列化可能で、直列化および直列化復元時に「Javaオブジェクト直列化仕様」によって定義された処理を受け取ります。 前述の特別な処理メソッドの宣言は、列挙型では無視されます。
レコード・クラスは、Serializable
を実装し、「Javaオブジェクト直列化仕様セクション1.13、"レコードの直列化"」によって定義された処理を受け取ることができます。 前述の特別な処理メソッドの宣言は、レコード・タイプでは無視されます。
直列化ランタイムは、各直列化可能クラスにバージョン番号serialVersionUIDを関連付けます。これは、直列化復元中に、直列化オブジェクトの送信側と受信側が、直列化に関して互換性のあるオブジェクトのクラスをロードしたかどうかを確認するために使われます。 対応する送信側のクラスとは異なるserialVersionUIDを持つオブジェクトのクラスを受信側がロードした場合、直列化復元ではInvalidClassException
が発生します。 フィールド名"serialVersionUID"
を宣言することによって、直列化可能クラスは独自のserialVersionUIDを明示的に宣言できます。このフィールド名は、次のようにstatic、final、およびlong
型である必要があります。
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;直列化可能クラスがserialVersionUIDを明示的に宣言しない場合、「Javaオブジェクト直列化仕様」で説明されているように、直列化ランタイムはクラスの様々な側面に基づいて、そのクラスのデフォルトのserialVersionUID値を計算します。 この仕様では、0 Lになる列挙型のserialVersionUIDを定義します。 ただし、列挙型以外のすべての直列化可能クラスではserialVersionUID値を明示的に宣言する「強く推奨される」です。デフォルトのserialVersionUID計算はコンパイラ実装によって異なる可能性のあるクラスの詳細に影響を与える可能性が高いため、直列化復元中に予期しない
InvalidClassException
が発生する可能性があります。 したがって、javaコンパイラの実装が異なってもserialVersionUID値の一貫性を確保にするには、直列化可能クラスがserialVersionUID値を明示的に宣言しなければいけません。 また、serialVersionUIDの明示的な宣言ではprivate
修飾子を使用することを強くお薦めします。このような宣言は直接的に宣言するクラスにのみ適用されるためです。つまり、serialVersionUIDフィールドは継承されるメンバーのように使いやすくありません。 配列クラスはserialVersionUIDを明示的に宣言できないため、常にデフォルトの計算値を持ちますが、配列クラスに関してはserialVersionUID値の一致要件は適用されません。 - 導入されたバージョン:
- 1.1
- 関連項目: