Serializableを実装します。
オブジェクト・ストリーム・クラスは、ObjectInputStreamとObjectOutputStreamです。 これらのクラスは、DataInputのサブインタフェースであるObjectInputか、DataOutputのサブインタフェースであるObjectOutputを実装しています。 つまり、データ・ストリームで扱われるプリミティブ・データのI/Oメソッドはすべて、オブジェクト・ストリームでも実装されています。 このため、オブジェクト・ストリームには、プリミティブ値とオブジェクト値を同時に含めることができます。 このことは、サンプル・プログラムのObjectStreamsで確認できます。 ObjectStreamsで作成されるアプリケーションは、前述のサンプル・プログラムDataStreamsで作成されるものと基本的には同じですが、いくつか変更点があります。 まず、価格には、小数値をより適切に表すBigDecimalオブジェクトを使用しています。 また、請求書の日付を表すCalendarオブジェクトを、データ・ファイルに書き込んでいます。
readObject()で返されるオブジェクトの型が期待したものと異なる場合、正しい型にキャストしようとするとClassNotFoundExceptionがスローされることがあります。 この単純なサンプル・プログラムではこうした事態は発生しないため、例外のキャッチはしていません。 代わりに、mainメソッドのthrows句にClassNotFoundExceptionを追加することで、このような問題を認識していることをコンパイラに通知しています。
writeObjectメソッドとreadObjectメソッドは、簡単に使用できる一方で、ある非常に高度なオブジェクト管理ロジックを含んでいます。 このことは、Calendarのような、単にプリミティブ値をカプセル化するだけのクラスには重要ではありません。 しかし、多くのオブジェクトには他のオブジェクトへの参照が含まれています。 readObjectがストリームからオブジェクトを再構成する場合、元のオブジェクトが参照していたすべてのオブジェクトを再構成できる必要があります。 さらに、これらのオブジェクトもまた別のオブジェクトを参照している可能性があり、こうした参照関係が延々と続く場合もあります。 このような状況において、writeObjectは網状に広がったオブジェクト参照構造の全体をトラバースして、その構造内のすべてのオブジェクトをストリームに書き込みます。 したがって、writeObjectを1回呼び出しただけで、大量のオブジェクトがストリームに書き込まれる場合があります。
この状況を、次の図で示します。ここでは、aという名前の1つのオブジェクトを書き込むために、writeObjectが呼び出されます。 このオブジェクトには、bおよびcというオブジェクトへの参照が含まれ、さらにbにはdおよびeへの参照が含まれます。 writeobject(a)を呼び出すと、aだけではなく、aの再構成に必要なすべてのオブジェクトも書き込まれます。このため、この網状の構造内にある他の4つのオブジェクトも書き込まれることになります。 aがreadObjectによって再度読み取られると、他の4つのオブジェクトも同様に読み取られ、元のオブジェクト参照のすべてが維持されます。

複数の参照先オブジェクトのI/O
obというオブジェクトをストリームに2回書き込んでいます。
Object ob = new Object(); out.writeObject(ob); out.writeObject(ob);
writeObjectはreadObjectに対応させる必要があるので、このストリームを再度読み取るコードは次のようになります。
Object ob1 = in.readObject(); Object ob2 = in.readObject();
ob1とob2という2つの変数は、同じ1つのオブジェクトへの参照となります。
ただし、1つのオブジェクトが別々の2つのストリームに書き込まれる場合は、そのオブジェクトは実際に複製されます。つまり、1つのプログラムで両方のストリームを再度読み取ると、2つの異なるオブジェクトを確認できます。