222

クラスがEclipseでSerializableを実装する場合、2つのオプションがあります。デフォルトを追加するserialVersionUID(1L)か、生成されserialVersionUID(3567653491060394677L)ます。最初の方がかっこいいと思いますが、2番目のオプションを使用している人を何度も見ました。生成する理由はありますlong serialVersionUIDか?

4

11 に答える 11

93

私の知る限り、これは以前のリリースとの互換性のためだけです。これは、以前にserialVersionUIDの使用を怠った後、互換性があるはずであるがシリアル化が中断する原因となる変更を加えた場合にのみ役立ちます。

詳細については、Javaシリアル化仕様を参照してください。

于 2009-05-20T14:44:50.483 に答える
78

シリアル化バージョンUIDの目的は、オブジェクトの有効なシリアル化を実行するために、クラスのさまざまなバージョンを追跡することです。

アイデアは、クラスの特定のバージョンに固有のIDを生成することです。このIDは、シリアル化されたオブジェクトの構造に影響を与える新しいフィールドなど、クラスに新しい詳細が追加されると変更されます。

常に同じIDを使用するなど1L、将来、クラス定義が変更されてシリアル化されたオブジェクトの構造が変更された場合、オブジェクトを逆シリアル化しようとすると問題が発生する可能性が高くなります。

IDを省略した場合、Javaは実際にはオブジェクトのフィールドに基づいてIDを計算しますが、これはコストのかかるプロセスであると思われるため、手動でIDを提供するとパフォーマンスが向上します。

クラスのシリアル化とバージョン管理について説明している記事へのリンクは次のとおりです。

于 2009-05-20T14:45:33.540 に答える
21

生成されたものの主な理由は、すでにコピーが永続化されているクラスの既存のバージョンと互換性を持たせるためです。

于 2009-05-20T14:45:43.697 に答える
15

の「長い」デフォルトは、 Javaシリアル化仕様serialVersionUIDで定義されているデフォルト値であり、デフォルトのシリアル化動作から計算されます。

したがって、デフォルトのバージョン番号を追加すると、構造的に何も変更されていない限り、クラスはより高速に(逆)シリアル化されますが、クラスを変更(フィールドの追加/削除)する場合は、シリアルナンバー。

既存のビットストリームと互換性がある必要がない場合は、そこに配置1Lして、何かが変更されたときに必要に応じてバージョンをインクリメントできます。つまり、変更されたクラスのデフォルトのシリアル化バージョンが古いクラスのデフォルトのバージョンと異なる場合です。

于 2009-05-20T14:49:37.073 に答える
15

を実装するクラスを定義するたびに、必ず serialVersionUID を作成する必要がありますjava.io.Serializable。そうしないと、自動的に作成されますが、これは悪いことです。自動生成された serialVersionUID は、クラスのメソッド シグネチャに基づいているため、後でクラスを変更してメソッドを追加すると (たとえば)、クラスの「古い」バージョンのシリアル化解除は失敗します。起こり得ることは次のとおりです。

  1. serialVersionUID を定義せずに、クラスの最初のバージョンを作成します。
  2. クラスのインスタンスを永続ストアにシリアル化します。serialVersionUID が自動的に生成されます。
  3. クラスを変更して新しいメソッドを追加し、アプリケーションを再デプロイします。
  4. ステップ 2 でシリアライズされたインスタンスをデシリアライズしようとしましたが、自動生成された別の serialVersionUID を持っているため、(成功するはずのときに) 失敗します。
于 2011-03-23T13:23:12.847 に答える
7

serialVersionUIDを指定しない場合、Javaはその場で1つ作成します。生成されたserialVersionUIDはその番号です。クラス内で以前のシリアル化されたバージョンと実際には互換性がないものを変更したが、ハッシュを変更した場合は、生成された非常に大きな数のserialVersionUID(またはエラーメッセージからの「期待される」数)を使用する必要があります。 。それ以外の場合は、自分ですべてを追跡している場合は、0、1、2...の方が適しています。

于 2009-05-20T14:45:50.327 に答える
1

まあ、serialVersionUID は、「静的フィールドはシリアル化されない」という規則の例外です。ObjectOutputStream は、毎回 serialVersionUID の値を出力ストリームに書き込みます。ObjectInputStream はそれを読み返し、ストリームから読み取った値がクラスの現在のバージョンの serialVersionUID 値と一致しない場合、InvalidClassException をスローします。さらに、シリアル化するクラスで正式に宣言された serialVersionUID がない場合、コンパイラは、クラスで宣言されたフィールドに基づいて生成された値を自動的に追加します。

于 2012-12-11T10:16:54.153 に答える
0

多くの場合、デフォルトIDは一意ではないためです。そのため、独自のコンセプトを作成するためのIDを作成します。

于 2011-09-16T12:35:53.883 に答える
0

シリアル化バージョン UID の目的は、オブジェクトの有効なシリアル化を実行するために、クラスのさまざまなバージョンを追跡することです。

アイデアは、クラスの特定のバージョンに固有の ID を生成することです。この ID は、シリアル化されたオブジェクトの構造に影響を与える新しいフィールドなど、クラスに新しい詳細が追加されたときに変更されます。

簡単な説明:

データをシリアライズしていますか?

シリアライゼーションとは、基本的にクラスデータをファイル/ストリーム/などに書き込むことです。逆シリアル化は、そのデータをクラスに読み戻すことです。

生産に入る予定はありますか?

重要でない/偽のデータで何かをテストしているだけであれば、心配する必要はありません (シリアライゼーションを直接テストしている場合を除きます)。

これは最初のバージョンですか?

その場合は、serialVersionUID=1L を設定します。

これは 2 番目、3 番目などの製品バージョンですか?

ここで、serialVersionUID について心配する必要があり、詳細に調べる必要があります。

基本的に、読み書きが必要なクラスを更新する際にバージョンアップを正しく行わないと、古いデータを読み込もうとするとエラーが発生します。

于 2020-04-24T16:55:29.887 に答える