モジュール java.base
パッケージ java.io

クラスObjectOutputStream

java.lang.Object
java.io.OutputStream
java.io.ObjectOutputStream
すべての実装されたインタフェース:
Closeable, DataOutput, Flushable, ObjectOutput, ObjectStreamConstants, AutoCloseable

public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants
ObjectOutputStreamは、プリミティブ・データ型とJavaオブジェクトのグラフをOutputStreamに書き込みます。 これらのオブジェクトを読み込む(再構築する)にはObjectInputStreamを使います。 オブジェクトの持続的記憶は、そのストリームのためのファイルを使えば可能です。 ストリームがネットワーク・ソケット・ストリームの場合は、ほかのホストやほかのプロセス上でオブジェクトを再構築することもできます。

ストリームに書き込めるのはjava.io.Serializableインタフェースをサポートするオブジェクトだけです。 各直列化可能オブジェクトのクラスは、クラスの名前とシグネチャ、オブジェクトのフィールドと配列、および初期オブジェクトから参照されるほかのすべてのオブジェクトのクロージャを含めてコード化されます。

オブジェクトをストリームに書き込むにはwriteObjectメソッドを使います。 Stringや配列を含む任意のオブジェクトがwriteObjectによって書き込まれます。 複数のオブジェクトまたはプリミティブも、ストリームへの書込みが可能です。 オブジェクトを読み込むときは、対応するObjectInputstreamから同じ型として、かつ書き込まれたときと同じ順序で読み込まなければいけません。

プリミティブ・データ型をストリームに書き込むには、DataOutputの適切なメソッドを使います。 Stringを書き込む場合はwriteUTFメソッドを使います。

オブジェクトのデフォルトの直列化メカニズムは、オブジェクトのクラス、クラスのシグネチャ、およびすべての非transientおよび非staticフィールドの値を書き込みます。 ほかのオブジェクトへの参照(transientおよびstaticフィールドは除く)があれば、これらのオブジェクトも書き込まれます。 単一オブジェクトへの多重参照は参照共有メカニズムによりエンコードされ、オブジェクトのグラフを、オリジナルが書き込まれたときの形状に復元することができます。

たとえば、ObjectInputStreamの例で読み取ることができるオブジェクトを書き込む場合:

     try (FileOutputStream fos = new FileOutputStream("t.tmp");
          ObjectOutputStream oos = new ObjectOutputStream(fos)) {
         oos.writeObject("Today");
         oos.writeObject(LocalDateTime.now());
     } catch (Exception ex) {
         // handle exception
     }

直列化および直列化復元プロセス中に特別な処理を必要とする直列化可能なクラスは、次のシグネチャを持つメソッドを実装する必要があります:

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

メソッド名、修飾子、戻り型、およびパラメータの数とタイプは、直列化または直列化復元で使用されるメソッドと完全に一致する必要があります。 これらのシグネチャと一致するチェック済例外をスローするためにのみ、メソッドを宣言する必要があります。

writeObjectメソッドは、その特定のクラスのオブジェクトの状態を書き込んで、対応するreadObjectメソッドがオブジェクトの状態を復元できるようにする役割を担います。 このメソッドは、オブジェクトのスーパー・クラスやサブクラスに属する状態に関与する必要はありません。 状態を保存するには、writeObjectメソッドを使って個々のフィールドをObjectOutputStreamに書き込むか、またはDataOutputがサポートするプリミティブ・データ型用のメソッドを使用します。

直列化では、java.io.Serializableインタフェースを実装しないオブジェクトのフィールドは書き込みません。 直列化可能でないオブジェクトのサブクラスを直列化可能にすることができます。 この場合、直列化可能でないクラスは、そのフィールドを初期化できるようにするため、引数なしのコンストラクタを持つ必要があります。 この場合、直列化可能でないクラスの状態を保存および復元するのは、サブクラスの責任になります。 そのクラスのフィールドがアクセス可能である(public、package、またはprotected)場合、あるいは状態の復元に利用できるsetメソッドやgetメソッドがある場合がしばしばあります。

writeObjectおよびreadObjectメソッドでNotSerializableExceptionをスローするように実装しておくと、オブジェクトの直列化を防止できます。 例外がObjectOutputStreamにキャッチされ、直列化処理が異常終了します。

Externalizableインタフェースを実装すると、オブジェクトの直列化された形式の内容および形式をオブジェクト側が完全に制御することが可能になります。 ExternalizableインタフェースのメソッドであるwriteExternalとreadExternalは、オブジェクトの状態を保存および復元するために呼び出されます。 これらのメソッドは、クラスによって実装された場合には、ObjectOutputとObjectInputのすべてのメソッドを使って、自身の状態の書き込みおよび読込みを行うことができます。 どのようなバージョンであっても処理できるようにするのは、オブジェクトの責任です。

enum定数の直列化は、通常の直列化可能または外部化可能オブジェクトとは異なります。 enum定数の直列化された形式を構成するのは、その名前だけです。定数のフィールド値は転送されません。 enum定数を直列化するには、その定数のnameメソッドによって返される文字列をObjectOutputStreamで書き込みます。 他の直列化可能または外部化可能オブジェクトと同様に、enum定数は直列化ストリームにその後出現する後方参照のターゲットとして機能できます。 enum定数を直列化するプロセスをカスタマイズすることはできません。enum型で定義された、クラス固有のwriteObjectメソッドおよびwriteReplaceメソッドは、直列化復元の間は無視されます。 同様に、serialPersistentFieldsまたはserialVersionUIDのフィールド宣言もすべて無視されます。すべてのenum型は0Lで固定されたserialVersionUIDを持ちます。

直列化可能フィールドおよび外部化可能データを除くプリミティブ・データは、ブロック・データ・レコードとしてObjectOutputStreamに書き込まれます。 ブロック・データ・レコードは、ヘッダーとデータで構成されます。 ブロック・データのヘッダーは、マーカーおよびヘッダーに続くバイト数で構成されます。 連続するプリミティブ・データの書込みは、1つのブロック・データ・レコードにマージされます。 ブロック・データ・レコードに使用されるブロック係数は1024バイトです。 各ブロック・データ・レコードは、1024バイトまで埋め込まれるか、ブロック・データ・モードの終了まで書き込まれます。 ObjectOutputStreamのメソッドwriteObject、defaultWriteObject、およびwriteFieldsを呼び出すと、最初に既存のブロック・データ・レコードが終了されます。

レコードの直列化は、通常の直列化可能オブジェクトまたは外部化可能オブジェクトとは異なります。「レコード直列化」を参照してください。

導入されたバージョン:
1.1
外部仕様
関連項目: