3

次の Java 例外クラスを検討してください。

public class BarException extends RuntimeException {
    // [...]
}

public class FooException extends BarException {
    private static final long serialVersionUID = -5322002268075295537L;

    // [...]
}

から直接派生するBarExceptionように、継承階層を削除して更新したい場合、値を変更する必要がありますか?FooExceptionRuntimeExceptionserialVersionUID

// FooException with updated inheritance hierarchy
public class FooException extends RuntimeException {
    private static final long serialVersionUID = ???;

    // [...]
}
4

4 に答える 4

5

はい。「クラスを階層の上または下に移動する」と、シリアル化の仕様に従って、以前にシリアル化されたインスタンスとの互換性がなくなります。

于 2009-09-14T11:27:26.193 に答える
2

仕様が混乱と議論を引き起こすほど不明確であり、明確な答えが出ていないことを考えると、残された唯一のオプションは経験的証拠を信頼することです.

上記の質問から、FooException派生元からBarException派生し、継承チェーンからRuntimeException削除する例を取り上げてBarException、さまざまな組み合わせでシリアル化と逆シリアル化を試すサンプル アプリケーションをまとめました。

次の結果が得られます。

を変更しない限り、オリジナルを更新済みとしてserialVersionUID正常にシリアライズおよびデシリアライズできその逆も可能です。FooExceptionFooException

次の警告が適用されます。

  • 私は JDK 1.5.0_07 を使用していますが、他のバージョンではこれを試していません。
  • FooExceptionintタイプおよびのメンバーがありException、これらは正常に逆シリアル化されます。
  • BarExceptionにメンバーを追加しませんRuntimeException
于 2009-10-15T07:27:38.917 に答える
2

Java 1.5 シリアライゼーション仕様では、継承階層からクラスを削除することは互換性のある変更であると示唆されているため、変更はserialVersionUID必要ありません。

に関連するシリアライゼーション ストリーム内の追加情報はBarException、 new にデシリアライズするときに無視されますFooException(これは から直接派生しますRuntimeException)。

于 2009-09-14T11:26:34.760 に答える
0

技術的には可能ですが、システムがシリアル化されたオブジェクトを永続化するかどうか、およびリファクタリングされた新しいコードのデプロイ方法を制御するかどうかによって異なります。

永続化を行わず、展開全体を新しいバージョンのコードで更新する場合、serialVersionUID.

于 2009-09-15T11:16:58.777 に答える