JavaTM Platform
Standard Ed. 6

java.io
インタフェース Serializable

既知のサブインタフェースの一覧:
AdapterActivator, Attribute, Attribute, Attributes, BindingIterator, ClientRequestInfo, ClientRequestInterceptor, Codec, CodecFactory, Control, Current, Current, Current, CustomValue, DataInputStream, DataOutputStream, Descriptor, DHPrivateKey, DHPublicKey, DocAttribute, DomainManager, DSAPrivateKey, DSAPublicKey, DynAny, DynAnyFactory, DynArray, DynEnum, DynFixed, DynSequence, DynStruct, DynUnion, DynValue, DynValueBox, DynValueCommon, ECPrivateKey, ECPublicKey, ExtendedRequest, ExtendedResponse, Externalizable, IdAssignmentPolicy, IDLEntity, IDLType, IdUniquenessPolicy, ImplicitActivationPolicy, Interceptor, IORInfo, IORInterceptor, IORInterceptor_3_0, IRObject, Key, LifespanPolicy, Name, NamingContext, NamingContextExt, NotificationFilter, ObjectReferenceFactory, ObjectReferenceTemplate, ORBInitializer, ORBInitInfo, PBEKey, POA, POAManager, Policy, PolicyFactory, PrintJobAttribute, PrintRequestAttribute, PrintServiceAttribute, PrivateKey, PublicKey, QueryExp, RelationType, RemoteRef, RequestInfo, RequestProcessingPolicy, RSAMultiPrimePrivateCrtKey, RSAPrivateCrtKey, RSAPrivateKey, RSAPublicKey, RunTime, SecretKey, ServantActivator, ServantLocator, ServantManager, ServantRetentionPolicy, ServerRef, ServerRequestInfo, ServerRequestInterceptor, StreamableValue, SupportedValuesAttribute, ThreadPolicy, UnsolicitedNotification, ValueBase, ValueExp

public interface Serializable

クラスの直列化可能性は、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 メソッドは、その特定のクラスのオブジェクトの状態を書き込んで、対応する readObject メソッドがオブジェクトの状態を復元できるようにする役割を担います。out.defaultWriteObject を呼び出すことによって、オブジェクトのフィールドを保存するためのデフォルトの機構を呼び出すことができます。このメソッドは、そのスーパークラスやサブクラスに属する状態に関与する必要はありません。状態を保存するには、writeObject メソッドを使って個々のフィールドを ObjectOutputStream に書き込むか、または DataOutput がサポートする基本データ型用のメソッドを使用します。

readObject メソッドは、ストリームからの読み込みとクラスフィールドの復元を行う役割を担います。このメソッドは、in.defaultReadObject メソッドを呼び出して、オブジェクトの非 static フィールドおよび非 transient フィールドを復元するためのデフォルトの機構を呼び出すことができます。defaultReadObject メソッドは、ストリームの情報を使用して、現在のオブジェクト内で対応するように指定されたフィールドとともに、ストリームに保存されているオブジェクトのフィールドを割り当てます。これで、新しいフィールドを追加できるようにクラスが拡張されるケースが処理されます。このメソッドは、そのスーパークラスやサブクラスに属する状態に関与する必要はありません。状態を保存するには、writeObject メソッドを使って個々のフィールドを ObjectOutputStream に書き込むか、または DataOutput がサポートする基本データ型用のメソッドを使用します。

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 を持つオブジェクトのクラスを受信側がロードした場合、直列化復元では InvalidClassException が発生します。フィールド名 "serialVersionUID" を宣言することによって、直列化可能クラスは独自の serialVersionUID を明示的に宣言できます。このフィールド名は、次のように static、final、および long 型でなければなりません。

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
 
直列化可能クラスが serialVersionUID を明示的に宣言しない場合、直列化ランタイムは「Java(TM) オブジェクト直列化仕様」で説明されているように、クラスのさまざまな側面に基づいて、クラスの serialVersionUID のデフォルト値を計算します。ただし、すべての直列化可能クラスが serialVersionUID 値を明示的に宣言することを強くお勧めします。これは、デフォルトの serialVersionUID の計算が、コンパイラの実装によって異なる可能性のあるクラスの詳細にきわめて影響を受けやすく、直列化復元中に予期しない InvalidClassException が発生する可能性があるためです。したがって、java コンパイラの実装が異なっても serialVersionUID 値の一貫性を確保にするには、直列化可能クラスが serialVersionUID 値を明示的に宣言しなければなりません。また、serialVersionUID の明示的な宣言では private 修飾子を使用することを強くお勧めします。このような宣言は直接的に宣言するクラスにのみ適用されるためです。つまり、serialVersionUID フィールドは継承されるメンバーのように使いやすくありません。配列クラスは serialVersionUID を明示的に宣言できないため、常にデフォルトの計算値を持ちますが、配列クラスに関しては serialVersionUID 値の一致要件は適用されません。

導入されたバージョン:
JDK1.1
関連項目:
ObjectOutputStream, ObjectInputStream, ObjectOutput, ObjectInput, Externalizable


JavaTM Platform
Standard Ed. 6

バグの報告と機能のリクエスト
さらに詳しい API リファレンスおよび開発者ドキュメントについては、Java SE 開発者用ドキュメントを参照してください。開発者向けの詳細な解説、概念の概要、用語の定義、バグの回避策、およびコード実例が含まれています。

Copyright 2006 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。