質問

私はおそらくこれについていくつかのダウン投票の危険を冒しています。

新しいクラスに明示的にserialVersionUIDを指定するのは悪いようです。レイアウトに変更があるべき場合に変更しない場合と、変更すべきでない場合に変更する場合の2つのケースを考えてください。

いつ変更すべきかが変更されないのは、明示的な場合のみです。この場合、非常に微妙で見つけにくいバグが発生します。特に開発中、クラスのレイアウトが頻繁に変更される場合。ただし、明示的に指定されていない場合は変更され、逆シリアル化が大規模に中断されます。ほとんどの場合、リポジトリをパージすることで解決されます。

あるべきではないときに変更することは、暗黙的である場合にのみ発生します。これはクラスレイアウトが変更されたまれなケースですが、古いシリアル化されたBLOBから非シリアル化する必要があります。これはQA中にキャッチされる可能性が高く( 5.2から5.2.1へのアップグレード後の奇妙なエラー、添付のスタックトレースを参照)、明示的な値を設定することで簡単に修正できます。

コメント?

役に立ちましたか?

解決

クラスレイアウトの変更以外の理由で起こるべきではない場合の変更-問題は、コンパイラの実装に依存することです。 Eclipseを使用してデバッグし、javacを使用して実稼働ビルドを実行すると、2つの互換性のないデータセットが発生する可能性があります。

他のヒント

作業中、問題が発生したため、serialVersionUIDの指定を明示的に禁止しています。

また、永続化するクラスは、内部にロジックのないデータを保存するためにのみ使用されるため、変更される唯一の方法は、データメンバーの変更によるものです。

ジョン・スキートが言ったことをさらに強調し、コメントに矛盾する:

"それが必要ない場合(つまり、同じクラスバージョンで常にシリアライズおよびデシリアライズする場合)、明示的な宣言を安全にスキップできます"

長期間シリアライズしておらず、同じクラスバージョンを使用している場合でも、引き続き問題が発生する可能性があります。クライアントとサーバーのコードを作成していて、サーバーとは異なるjvmバージョン/実装でクライアントコードを実行できる場合、互換性のないserialversionuidで同じ問題が発生する可能性があります。

要約すると、唯一の時間は「安全」です。 serialversionuidを指定しないのは、長期のシリアル化を行わず、シリアル化されたデータのすべてのコンシューマーが元のプロデューサーと同じjvm実装とバージョンを使用することが保証されている場合です。

要するに、serialversionuidを使用しない は、一般により有害な状況です。

シリアル化による長時間の永続化をサポートする必要がある場合、ほとんどの場合、カスタムコードを使用してこれをサポートし、 serialVersionUID を明示的に設定する必要があります。新しいコードで逆シリアル化可能。

これらのシナリオでは、クラスが変更されたときにすべてのケースを正しく処理するために、すでにかなりの注意が必要であるため、serialVersionUIDが最も問題になりません。

それが必要ない場合(つまり、常に同じクラスバージョンでシリアライズおよびデシリアライズする場合)、計算された値によって正しいバージョンが使用されることが保証されるため、明示的な宣言を安全にスキップできます。

serialVersionUID に行くかどうか(そうすることをお勧めします)、シリアル互換性のための包括的なテストセットの作成を検討する必要があります。

シリアル形式を注意して設計することも価値があります。これは事実上パブリックAPIです。

リモートメソッド呼び出しにシリアル化を使用している場合、たとえばクライアントクラスとサーバークラスとjvmが同じEJBを呼び出しますが、これは間違いなく最も一般的な使用方法であり、serialVersionUIDを明示的に設定すると(たとえばeclipseが示唆するように) serialVersionUIDが修正されているため、互換性のないクラスインスタンスが互換性があるものとして扱われる不可解なバグ。低レベルのシリアル化中にリモート呼び出しが静かに失敗し、オブジェクトの状態に一貫性がない場合にのみ問題が発生します。問題の原因を見つけるのは、クライアントとサーバーのクラスが何らかの形で異なることに気付いたときだけです(ただし、serialVersionUIDはもちろん違います)。私の経験では、この理由でserialVersionUIDを設定することは、害よりも害をもたらします。

一方、古いデータを読み込むようにserialVersionUIDを明示的に設定した場合、互換性のないバージョンで定義を読み込むことになり、オブジェクトが一貫性のない状態または不完全な状態になる可能性があります。この場合、serialVersionUIDの設定は、別の問題の回避策です。

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