0

問題: クラス A は Serializable を実装します クラス B は A を拡張し、Serializable を実装します

ここで、クラス B をランタイム タイプとしてのみ使用してシリアライズします。だから私はリストを持っています:

List<A> lst = new ArrayList<A>();
lst.add(new B());
...
objectOutputStream.writeObject(lst.get(i)); //this write compiler-type A, runtime-type B

ここで逆シリアル化すると、java.io.OptionalDataException エラーが発生します。とにかく疑問に思っているのは、私のオブジェクトが正しいランタイムタイプになる方法です。逆シリアル化:

A a = (A) objectInputStream.readObject();

これは、シリアライゼーション時にクラス B のランタイム タイプにつながるか、または A の ear サブクラスのデフォルトのシリアライゼーションを上書きする必要がありますか?

明らかなことを見逃さなかったことを願っています。

前もって感謝します : )

編集:

すべての回答のおかげで、自分の過ちを理解するのに本当に役立ちました。

私が(答えたように) in.read(arr); を使用したため、例外がスローされました。それはデータを完全に読み取らないことにつながるため、オブジェクトを正しく逆シリアル化できませんでした(もちろんそうではありません)- readFully に変更した後、期待どおりに機能しました。

4

2 に答える 2

1

提供された情報では、OptionalDataException が発生した理由を特定できません。A はシリアライズ可能であるため、B は A を拡張するため、B はシリアライズ可能になります。list.get(i) がオブジェクト B であると仮定すると、objectOutputStream.writeObject(list.get(i)) はオブジェクト B をストリームに書き込みます。そしてそれを読み返すと、オブジェクト B が返されます。

メソッド ObjectOutputStream.writeObject は Object を引数として受け入れるため、タイプ eraser の引数は無関係です。

クラス A または B に対してプライベート メソッド writeObject および readObject を定義しますか? これらのメソッドを定義する場合は、オブジェクトとプリミティブ データを正しい順序で読み書きするようにしてください。

于 2012-07-08T02:59:27.880 に答える
0

わかりました..これを試してください......

1.まず第一に、シリアライズ可能はマーカー/タグインターフェースであり、このクラスのオブジェクトはシリアライズが許可されていると言い、スーパークラスがシリアライズ可能である場合、そのサブクラスは自動的にシリアライズ可能になります...だからBを作る必要はありませんA をシリアライズ可能に拡張します。

2. readObject() を使用してオブジェクトを読み戻すと言うと、それはオブジェクト形式になるため、その型にキャストする必要があります。

例えば:

GamePlayer gp1 = (GamePlayer) os.readObject(); //os is ObjectInputStream instance

于 2012-07-08T14:00:03.627 に答える