目次 | 前の項目 | 次の項目 | Java オブジェクト直列化仕様 |
Serializable オブジェクトの場合、readObject
メソッドによって、クラスがそれ独自のフィールドの直列化復元を制御することができます。そのシグニチャーを次に示します。private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException;Serializable オブジェクトの各サブクラスは、それ独自のreadObject
メソッドを定義することができます。このメソッドがクラスに実装されていない場合は、defaultReadObject
によって与えられるデフォルトの直列化が使用されます。 実装されている場合は、そのクラスは、そのスーパータイプやサブタイプのフィールドではなく、それ独自のフィールドだけを復元する責任があります。クラスの
readObject
メソッドが実装されていれば、そのメソッドはそのクラスの状態を復元する責任があります。transient または static かどうかには関係なく、オブジェクトのすべてのフィールドの値に、そのフィールドタイプのデフォルトの値が設定されます。ObjectInputStream
のdefaultReadObject
メソッドまたはreadFields
メソッドを一度 (一度だけ) 呼び出してからでないと、対応するwriteObject
メソッドによって書き込まれた任意指定のデータを読み込むことはできません。任意指定のデータを読み込まない場合でも、defaultReadObject
またはreadFields
を一度呼び出す必要があります。クラスのreadObject
メソッドが、このクラスのストリーム内に存在する任意指定部分よりも多くのデータを読み込もうとすると、バイトの読み込みでは-1
が返され、プリミティブデータの読み込み (readInt
、readFloat
など) では EOFException がスローされ、オブジェクトの読み込みではeof
フィールドがtrue
に設定されたOptionalDataException
がスローされます。この任意指定データの形式、構造体、バージョン管理の責任のすべては、そのクラスにあります。任意指定データの形式および構造を文書化する場合は、
readObject
メソッドに対する javadoc コメント内の@serialData
javadoc タグを使う必要があります。復元するクラスが読み込みストリーム内に存在しない場合、
readObjectNoData
メソッドが定義されていれば、(readObject
の代わりに) そのメソッドが呼び出され、定義されていなければ、フィールドは適切なデフォルト値に初期化されます。詳細は、「3.5 readObjectNoData メソッド」 を参照してください。
ObjectInputStream
からのオブジェクトの読み込みは、新しいオブジェクトの作成に似ています。新しいオブジェクトのコンストラクタがスーパークラスからサブクラスという順番で呼び出されるのと同様に、ストリームから読み込まれるオブジェクトは、スーパークラスからサブクラスに直列化復元されます。直列化復元中に、各Serializable
サブクラスに対して、コンストラクタではなくreadObject
またはreadObjectNoData
メソッドが呼び出されます。コンストラクタと
readObject
メソッドでもう 1 つ似ている点は、どちらも、完全に構築されていないオブジェクト上にメソッドを呼び出すことができる点です。オブジェクトの構築中に呼び出されるオーバーライド可能なメソッド (private、static、final のどれでもないもの) は、サブクラスによってオーバーライドされる可能性があります。オブジェクトの構築段階に呼び出されるメソッドは、コンストラクタかreadObject
またはreadObjectNoData
メソッドによって現在初期化されている型ではなく、そのオブジェクトの実際の型によって解釈処理されます。したがって、readObject
またはreadObjectNoData
メソッド内からオーバーライド可能なメソッドを呼び出すと、スーパークラスが完全に初期化される前に意図しないサブクラスが呼び出される可能性があります。