[目次] [前項目] [次項目]

オブジェクト入力インタフェース


トピック:

ObjectInputStream クラス

クラス ObjectInputStream は、オブジェクトの直列化復元を実装するためのものです。このクラスは、すでに直列化復元されたオブジェクト群などのストリームの状態を管理します。このクラスのメソッドを使えば、ObjectOutputStream によって書き込まれたストリームから、プリミティブ型やオブジェクトを読み込むことができます。このクラスは、それが参照するオブジェクトをストリームから復元します。

package java.io;

public class ObjectInputStream
	extends InputStream
	implements ObjectInput, ObjectStreamConstants
{
	public ObjectInputStream(InputStream in)
		throws StreamCorruptedException, IOException;

	public final Object readObject()
		throws OptionalDataException, ClassNotFoundException, 
			IOException;

	public final void defaultReadObject()
		throws IOException, ClassNotFoundException,
			NotActiveException;

	public synchronized void registerValidation(
		ObjectInputValidation obj, int prio)
		throws NotActiveException, InvalidObjectException;

	protected Class resolveClass(ObjectStreamClass v)
		throws IOException, ClassNotFoundException;

	protected Object resolveObject(Object obj)
	    	throws IOException;

	protected final boolean enableResolveObject(boolean enable)
		throws SecurityException;

	protected void readStreamHeader()
		throws IOException, StreamCorruptedException;

	public int read() throws IOException;

	public int read(byte[] data, int offset, int length)
		throws IOException

	public int available() throws IOException;

	public void close() throws IOException;

	public boolean readBoolean() throws IOException;

	public byte readByte() throws IOException;

	public int readUnsignedByte()  throws IOException;

	public short readShort()  throws IOException;

	public int readUnsignedShort() throws IOException;

	public char readChar()  throws IOException;

	public int readInt()  throws IOException;

	public long readLong()  throws IOException;

	public float readFloat() throws IOException;

	public double readDouble() throws IOException;

	public void readFully(byte[] data) throws IOException;

	public void readFully(byte[] data, int offset, int size)
		throws IOException;

	public int skipBytes(int len) throws IOException;

	public String readLine() throws IOException;

	public String readUTF() throws IOException;
}
ObjectInputStream 構築子には InputStream が必要です。この構築子は、readStreamHeader を呼び出して読み込み、対応する ObjectOutputStream.writeStreamHeader メソッドによって書き込まれたヘッダーとバージョンを検査します。

ストリームからオブジェクトを直列化復元するには、readObject メソッドを使用します。このメソッドは、このストリームを読んで、オブジェクトを再構築します。

  1. ブロックデータレコードがストリームにあると、BlockDataException をスローし、使用可能なバイト数を知らせます。
  2. ストリームのオブジェクトが null なら、null を返します。
  3. ストリームのオブジェクトが前のオブジェクトに対するハンドルなら、そのオブジェクトを返します。
  4. ストリームのオブジェクトが文字列なら、UTF コード化を読み、それとそのハンドルを、認識されているオブジェクト・セットに追加し、その文字列を返します。
  5. ストリームのオブジェクトがクラスなら、その ObjectStreamClass 記述子を読み、それとそのハンドルを、認識されているオブジェクト・セットに追加し、対応するクラスオブジェクトを返します。
  6. ストリームのオブジェクトが ObjectStreamClass なら、その名前と serialVersionUID とフィールドを読み、それとそのハンドルを、認識されているオブジェクト・セットに追加します。このストリームに対し resolveClass メソッドを呼び出して、この記述子のローカルクラスを入手します。そのクラスが見つからないときは例外をスローします。ObjectStreamClass オブジェクトを返します。
  7. ストリームのオブジェクトが配列なら、その ObjectStreamClass と配列の長さを読みます。その配列を割り当て、それとそのハンドルを、認識されているオブジェクト・セットに追加します。各要素をその型に適したメソッドを使って読み込み、それを配列に代入し、その配列を返します。
  8. その他のオブジェクトの場合は、そのオブジェクトの ObjectStreamClass がストリームから読み込まれます。その ObjectStreamClass のローカルクラスが取り出されます。このクラスは、直列化可能か外部化可能でなければなりません。
  9. そのクラスのインスタンスが割り当てられます。そのインスタンスとそのハンドルが、認識されているオブジェクト・セットに追加されます。内容が適切に復元されます。
  10. enableResolveObject によってオンにされていれば、resolveObject メソッドが、このオブジェクトが返されるすぐ前に呼び出されます。これによって、必要ならサブクラスがそれを置き換えることができます。resolveObject の呼び出しの値は、readObject から返されます。
プリミティブ型を読むためのすべてのメソッドは、ストリームのブロックデータレコードからバイトだけを使用します。ストリームの次のアイテムがオブジェクトのときにプリミティブデータの読み込みが行われると、読み込みメソッドは -1 か EOFException のうち、適切なものを返します。 プリミティブ型の値は、DataInputStream によってブロックデータレコードから読み込まれます。

スローされた例外は、そのトラバースの間に起きたエラーか、基本のストリームで起きた例外を反映したものです。例外がスローされた場合、基本のストリームは不明で使用不能な状態のままです。

ストリームでリセットトークンが起こると、ストリームのすべての状態は破棄されます。認識されているオブジェクトセットはクリアされます。

ストリームで例外トークンが起こると、その例外が読み込まれ、新しい WriteAbortedException がスローされます。このとき、停止を引き起こした例外が引数として指定されます。ストリームコンテキストは前に述べたようにリセットされます。

ストリームからオブジェクトのフィールドを読み込むには、defaultReadObject メソッドを使用します。このメソッドは、ストリームのクラス記述子を使って、名前と型によってストリームからそれらのフィールドを読み込みます。それらの値は、名前によって現行クラスの対応するフィールドに代入されます。バージョン化メカニズムの詳細については、互換性のある Javaの型展開 を参照してください。ストリームにない、オブジェクトのフィールドは、そのデフォルト値に設定されます。ストリームにあるがオブジェクトにない値は破棄されます。このような状態は主に、クラスの後のバージョンで、前のバージョンにはなかったフィールドを追加で書き込んだ場合に起こります。このメソッドは、クラスのフィールドを復元している間に readObject メソッドからのみ呼び出すことができます。それ以外のときに呼び出すと、NotActiveException がスローされます。

registerValidation メソッドを呼び出すと、オブジェクトが readObject の元の呼び出し側に返される前にグラフ全体が復元された際、コールバックを要求することができます。有効化コールバックの順序は、優先順次で制御することができます。高い値のコールバックは、低い値のものより前に呼び出されます。有効にされるオブジェクトは、ObjectInputValidation インタフェースをサポートし、validateObject メソッドを実装していなければなりません。有効化を登録するのは、クラスの readObject メソッドを呼び出す間でなければなりません。さもないと、NotActiveException がスローされます。registerValidation に指定されたコールバックオブジェクトが null の場合、InvalidObjectException がスローされます。

resolveClass メソッドは、直列化復元されている間と、そのクラス記述子が読み込まれた後で呼び出されます。サブクラスは、このメソッドを拡張して、ObjectOutputStream の対応するサブクラスによって書き込まれたクラスの他の情報を読むことができます。このメソッドは、与えられた名前と serialVersionUID をもつクラスを見つけ、返さなければなりません。デフォルトの実装では、このクラスは、クラスローダーをもつ readObject の最も近い呼び出し側のクラスローダーを呼び出すことによって、見つけられます。このクラスが見つからないと、ClassNotFoundException が通常スローされます。

resolveObjectメソッドは、直列化復元の際に、あるオブジェクトを別のオブジェクトの代わりにモニターしたり、あるオブジェクトで別のオブジェクトを置換したりすることを可能にするために、信頼されたサブクラスによって使用されます。オブジェクトの解決は、解決する最初のオブジェクトに対して readObject を呼び出す前に、enableResolveObject を呼び出して明示的に使用可能にしなければなりません。これを使用可能にすると、resolveObject は、それぞれの直列化可能オブジェクトに対して、それが readObject から最初に返される直前に 1 度だけ呼び出されます。サブクラスの実装では、オリジナルの代わりに代入されたり返されたりする置換オブジェクトが、返されることがあります。返されるオブジェクトは、一貫性があり、元のオブジェクトへの参照に必ず代入できる型のものでなければなりません。さもないと、ClassCastException が返されます。すべての代入では型の検査が行われます。ストリームにおける元のオブジェクトへのすべての参照は、置換オブジェクトへの参照によって置き換えられます。

enableResolveObject メソッドは、直列化復元の際に、あるオブジェクトを別のオブジェクトの代わりにモニターしたり、あるオブジェクトで別のオブジェクトを置換することを可能にするために、 ObjectOutputStream の信頼されたサブクラスによって使用されます。 オブジェクトの置換は、enableResolveObjecttrue 値で呼び出されるまでオフにされます。オブジェクトの置換は、その後で false を設定することによってオフにすることができます。前の設定が返されます。enableResolveObject メソッドは、置換を要求しているストリームが信頼できるかどうかを検査します。直列化復元されたオブジェクトへのすべての参照は、resolveObject メソッドへ返されます。オブジェクトの private 状態が意図せずに変更されることのないように、信頼されたストリームだけしか resolveObject を使用することはできません。信頼されたクラスとは、クラスローダーが null に等しいクラスのことです。

readStreamHeader メソッドは、ストリームのマジック番号とバージョンを読み込み、検査します。それらが一致しないと、StreamCorruptedMismatch がスローされます。

ObjectInputValidation インタフェース

このインタフェースを使うと、完全なグラフのオブジェクトが直列化復元されたとき、オブジェクトが呼び出されます。オブジェクトを有効にできない場合、このインタフェースは通常 ObjectInvalidException をスローします。validateObject の呼び出しで例外が起こると、有効化処理は停止され、InvalidObjectException がスローされます。

package java.io;

public interface ObjectInputValidation
{
	public void validateObject()
		throws InvalidObjectException;
}

readObject メソッド

Serializable オブジェクトの場合、readObject メソッドによって、クラスがそれ独自のフィールドの直列化復元を制御することができます。次はそのシグネチャです。

	private void readObject(ObjectInputStream stream)
		throws IOException;
Serializable オブジェクトの各サブクラスは、それ独自の readObject メソッドを定義することができます。このメソッドがクラスに実装されていない場合は、defaultReadObject によって与えられるデフォルトの直列化が使用されます。実装されている場合は、そのクラスは、そのスーパー型やサブ型のフィールドではなく、それ独自のフィールドだけを復元する責任があります。

クラスの readObject メソッドが実装されていれば、そのメソッドはそのクラスの状態を復元する責任があります。defaultReadObject は、対応する writeObject メソッドによって書き込まれた任意指定のデータを読み込む前に呼び出されなければなりません。このクラスに対するストリームの任意指定部分にある以上のデータを読み込もうとすると、ストリームは EOFException をスローします。任意指定データの形式、構造体、バージョン機能の責任は、完全にそのクラスにあります。

復元するクラスが、読み込まれているストリームにないと、そのフィールドは適切なデフォルト値に初期化されます。

readExternal メソッド

java.io.Externalizable を実装するオブジェクトは、readExternal メソッドを実装して、そのオブジェクトの状態全体を復元しなければなりません。このオブジェクトは、そのスーパークラスと連携してそれらの状態を復元する必要があります。ObjectInput のすべてのメソッドが、そのオブジェクトのプリミティブ型のフィールドとオブジェクトフィールドを復元するために使用できます。

	public void readExternal(ObjectInput stream)
		throws IOException;
readExternalメソッドは publicであるため、クライアントがストリームの既存オブジェクトを上書きする危険があります。



[目次] [前項目] [次項目]

Copyright (C) 1996, 1997 Sun Microsystems, Inc. All rights reserved.