Java Exceptionクラスが拡張する基本クラスを変更した場合、serialVersionUID値を更新する必要がありますか?

StackOverflow https://stackoverflow.com/questions/1420978

質問

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

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

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

    // [...]
}

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

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

    // [...]
}
役に立ちましたか?

解決 3

仕様が混乱と議論を引き起こすほど不明確であり、明確な答えが出ていないことを考えると、経験的証拠を信頼することが唯一の選択肢です。

上記の質問から、 RuntimeException から派生した BarException から派生した FooException の例を取得し、次に BarException 継承チェーンから、さまざまな組み合わせでシリアライゼーションとデシリアライゼーションを試すためのサンプルアプリケーションを作成しました。

次の結果が得られます。

serialVersionUID を変更しない限り、元の FooException を更新された FooException として正常にシリアライズおよびデシリアライズできます。 および逆も同様です。

次の注意事項が適用されます。

  • JDK 1.5.0_07を使用していますが、他のバージョンではこれを試していません。
  • FooException には、タイプ int および Exception のメンバーがあり、正常にデシリアライズされています。
  • BarException は、 RuntimeException に追加のメンバーを追加しません。

他のヒント

Java 1.5シリアル化仕様は、継承階層からクラスを削除することは互換性のある変更であるため、 serialVersionUID を変更する必要はないことを示唆しています。

新しい FooException RuntimeException から直接派生)に逆シリアル化する場合、 BarException に関連するシリアル化ストリームの追加情報は無視されます。 )。

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

永続化を行わず、新しいバージョンのコードで展開全体を更新する場合、 serialVersionUID を変更する必要はありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top