serialVersionUID
が自動生成されないのはなぜですか? どうやら古いクラスがキャッシュされているアプリケーション サーバーで問題が発生していました。
3 に答える
serialversionuid は危険なので自動生成されません。serialversionuid が設定されている場合、クラスの 2 つのバージョンがシリアル化に関して互換性があることを意味します。
Foo という名前のクラスがあり、serialversionuid (デフォルト) がなく、Foo のインスタンスをファイルにシリアライズするとします。後で、いくつかの新しいメンバーを Foo クラスに追加します。ファイルから Foo オブジェクトを逆シリアル化しようとすると、オブジェクトに互換性がないことを示すシリアル化エラーが発生します。それらは互換性がありません。これはあなたが望むものであり、デフォルトです。Foo クラスの新しいメンバーは、Foo の古いシリアル化されたインスタンスから初期化できないため、互換性がありません。
ここで、「どうでもいい。私のアプリケーションでは、これらのフィールドが初期化されていなくてもかまわない」と言うかもしれません。その場合は、新しいFoo クラスのserialversionuidを古いFoo クラスと同じに設定できます。これにより、オブジェクトがシリアライズ可能性に関して互換性があることが Java に通知され、Java は、古い Foo インスタンスを新しい Foo クラスにデシリアライズしても文句を言いません (ただし、新しいフィールドはまだ初期化されていません)。
初めて新しいクラスを作成し、serialversionuid を設定する場合は、コントラクトに入ります。その契約は、「同じsererialversionuidを持つこのクラスの将来のすべてのバージョンについて、状態とシリアライゼーションに関して互換性があることを保証します」です。
クラスを変更し、古いバージョンの逆シリアル化を明示的に禁止したい場合は、serialversionuid を新しい値に変更できます。これにより、古いオブジェクトを新しいクラス インスタンスに逆シリアル化しようとすると、例外がスローされます。
クラスの構造に基づいて、自動的に生成されます。構造が変更された場合、id が再生成されます (シリアライゼーション仕様によれば、これはクラスのハッシュです)。
したがって、明示的に定義する方がよいでしょうserialVersionUID
。
IDE として Eclipse を使用している場合は、serialVersionUID が見つからないという警告を右クリックすると、次の 2 つのオプションが表示されます。
1) 値が 1L の Eclipse デフォルトを定義します。または
2) ランダムに生成された long 値を定義する
シリアル化されたオブジェクトのバージョン管理に関心がある場合は、クラスを変更するたびに新しい値を手動で再生成する必要があります。Serializable インターフェースの Javadoc には、serialVersionUID をまったく宣言しない場合に何が起こるかについて、次のように書かれています。
シリアライズ可能なクラスが serialVersionUID を明示的に宣言しない場合、シリアライゼーション ランタイムは、Java(TM) オブジェクト シリアライゼーション仕様で説明されているように、クラスのさまざまな側面に基づいて、そのクラスのデフォルトの serialVersionUID 値を計算します。ただし、デフォルトの serialVersionUID 計算は、コンパイラの実装によって異なる可能性があるクラスの詳細に非常に敏感であり、逆シリアル化中に予期しない InvalidClassExceptions が発生する可能性があるため、すべてのシリアル化可能なクラスで serialVersionUID 値を明示的に宣言することを強くお勧めします。したがって、異なる Java コンパイラの実装間で一貫した serialVersionUID 値を保証するには、シリアライズ可能なクラスで明示的な serialVersionUID 値を宣言する必要があります。
実際には、serialVersionUID がクラスで定義されていない 2 つ以上のマシン (たとえば、Subversion からチェックアウト) で同一のソース コードを使用して開始した場合でも、クラスでコンパイラが生成した値はそれぞれで異なることがわかりました。コードがコンパイルされるときのマシン。これにより、開発中に紛らわしいエラーが発生する可能性があります。
新しいバージョンのクラス (または 2 つの JVM が非同期のシリアル化されたオブジェクトを相互に送信する、おそらくネットワークまたはソケット接続) の場合は、serialVersionUID の値を 1L に設定し、それを永久にそのままにしておきます。
http://download-llnw.oracle.com/javase/6/docs/api/java/io/Serializable.html