16

Serializableのインターフェイスについてを読むと、Thinking in java次のような文があります。

デフォルトのメカニズムを使用してオブジェクトの非一時的な部分を書き込む場合は、writeObject( ) の最初の操作として defaultWriteObject( ) を呼び出し、readObject( ) の最初の操作として defaultReadObject( ) を呼び出す必要があります。

docs.oracle.com 5.6.2 では:

writeObject/readObject メソッドの追加 - ストリームを読み取るバージョンにこれらのメソッドがある場合、readObject は、通常どおり、デフォルトのシリアライゼーションによってストリームに書き込まれた必要なデータを読み取ることが期待されます。オプションのデータを読み取る前に、まず defaultReadObject を呼び出す必要があります。writeObject メソッドは、通常どおり defaultWriteObject を呼び出して必要なデータを書き込み、その後、オプションのデータを書き込むことが期待されます。

それでdefaultWriteObject、最初に電話をかけず、その電話の前に何か別のことを書いた場合、問題はありますか? 試してみましたが、私の例ではまだうまく機能しているようです。では、問題があるとすれば、それはどのような状況で発生する可能性があるのでしょうか?

4

4 に答える 4

6

Java Object Serialization Specificationは、この件に関して曖昧です:

オブジェクトの状態を復元するために対応するメソッドが必要とするオプションのデータを書き込む前に、またはメソッドObjectOutputStreamのいずれかを 1 回 (しかも 1 回だけ) 呼び出す必要があります。オプションのデータが書き込まれていない場合でも、1回呼び出す必要があります。オプションのデータ (存在する場合) を書き込む前にorが呼び出されない場合、問題のメソッドを定義したクラスを が解決できない場合、インスタンスのデシリアライゼーションの動作は未定義です。defaultWriteObjectwriteFieldsreadObjectdefaultWriteObjectwriteFieldsdefaultWriteObjectwriteFieldsObjectInputStreamwriteObject

これは、問題が発生する可能性がある場合の例を示す古いスレッドです。

JBoss AS Jira チケットと別の例を次に示します。

于 2013-04-26T15:09:37.477 に答える
3

それはEffective Javaで説明されています:

すべてのインスタンス フィールドが一時的である場合、 defaultWriteObject および defaultReadObject を呼び出さなくても技術的には許容されますが、推奨されません。すべてのインスタンス フィールドが一時的であっても、defaultWriteObject を呼び出すとシリアル化されたフォームに影響を与えるため、柔軟性が大幅に向上します。結果として得られるシリアル化された形式により、下位互換性と上位互換性を維持しながら、後のリリースで非一時的なインスタンス フィールドを追加できます。インスタンスが新しいバージョンでシリアル化され、以前のバージョンで逆シリアル化された場合、追加されたフィールドは無視されます。以前のバージョンの readObject メソッドが defaultReadObject の呼び出しに失敗した場合、デシリアライゼーションは StreamCorruptedException で失敗します。

于 2015-08-01T12:53:11.333 に答える
2

ドキュメントのキーワードは"should" だと思います。これは、する必要がないことを意味します。

何よりもベストプラクティスだと思います。あなたのコードを初めて読んで、最初の行で読み取り/書き込みをデフォルトに設定したことがわかった場合、「わかりました。クラスの 90% で完了しました」と自分に言い聞かせ、処理するカスタム コードに集中できます。すべての非一時的で非静的なインスタンス変数..

最も重要なことは、同じ順序で読み書きすることです。それ以外は自由に好きなようにできます。

于 2013-04-26T15:11:05.973 に答える
0

それは、あなたが両側で何をしているのかを知っていて、「同じ」かそれ以上のことをするからだと思います...

BUT: 他のプログラマーが、あなたがデフォルトを使用していないことを知らずに、あなたのシリアライゼーションに対してデシリアライゼーションを作成した場合、おそらく推奨されている defaultReadObjectを使用し、奇妙な例外に遭遇するでしょう。

于 2013-04-26T15:11:27.200 に答える