3

インターフェースの立ち上げから、Serializableこのフィールドをすべてのクラスに組み込む必要がある理由に戸惑いました。このインターフェイスにはクラスをマークするための一意の識別子が必要であることを理解していますが、実行時にこれを生成できないのはなぜですか。たとえば、完全修飾クラス名のMD5ハッシュ、またはまれに重複を処理するために使用される同様の方法論を使用して生成できます(これは、とにかくIDを生成するように求められたときにeclipseが行うことです)。

それで、私が求めているのは(この投稿は標準ライブラリに対する単なる暴言ではありません)、フレームワークでシリアル化フィールドがどのように使用されているかということです。

MD5ハッシュを使用してserialVersionUIDフィールドを追加し、APIで受け入れられる方法で衝突を処理できるAspect(AspectJまたは他の言語で)を作成しようとしているため、知りたい理由。

うまくいけば結果を投稿します。

4

4 に答える 4

9

serialVersionUIDフィールドを持っている必要はありません。指定しない場合、Javaはクラスのフィールドとメソッドに基づいて生成します。

指定する理由serialVersionUIDは、メソッドが変更されたときに値が変更されないようにするためです。これは、シリアル化されたバイナリには影響しません。クラスについて考えてみましょう。

public class Person implements Serializable {
    private String name;
    public String getName() {
        return name;
    }
}

いいえserialVersionUIDが指定されました。実行すると、次のようserialver Personになります。

Person:    static final long serialVersionUID = 3793453319058452486L;

ここで、メソッドを追加することにしましたが、フィールドは同じままにしておきます。

public class Person implements Serializable {
    private String name;
    public String getName() {
        return name;
    }
    public Object foo() {
        return "bar";
    }
}

シリアル化されたバイナリは、古いバージョンと完全に互換性がありますが、serialVersionUID違いがあります。

Person:    static final long serialVersionUID = -6188734029437600310L;

別の場合serialVersionUID、逆シリアル化すると、serialVersionUIDの不一致エラーが発生します。serialVersionUID回避策は、任意の値に設定し(私は設定します1L)、フィールドが変更されるたびに変更することで、独自の宣言を行います。

この関連する質問「serialVersionUIDとは何ですか、なぜそれを使用する必要があるのですか?」も参照してください。より詳細な議論のために。

于 2012-09-07T01:12:08.110 に答える
4

このフィールドをすべてのクラスに組み込む必要がある理由

あなたはそうしない。

なぜ彼らは実行時にこれを生成できないのですか

あなたがそれをあなた自身で提供しない限り、彼らはそうします。

MD5ハッシュを使用してserialVersionUIDフィールドを追加するアスペクト(AspectJまたは他の言語で)を作成しようとしています

それは無意味でしょう。あなたはそれが何のためにあるのか理解していません。実行時に生成することはデフォルトですでに行われていることなので、提案は何の価値も追加しません。値は、オブジェクトのバージョン管理の互換性を実際に壊さないマイナーなクラス変更を吸収するために、コンパイル時に指定することで得られます。AOPを介してそれを達成することはできません。これはコーディングの決定です。

于 2012-09-07T01:19:18.303 に答える
0

Serializableインターフェース_

このインターフェースはjava.ioパッケージに含まれています。これは、マイナーな変更を保護するために実装され、実行時にユーザーwritesaveオブジェクトを有効にするために実装されます。このインターフェースは、JVMがコンポーネントの新しいバージョンを見つけることができるように開発者がそれらを拡張できるため、すべてのswingコンポーネントによって実装されますYour class

SerialVersionUID

serialVersionUID、Serializableクラスのバージョン管理として使用されます。JVM will did it for you automaticallySerializableクラスのさまざまな側面に基づいて、serialVersionUIDを明示的に宣言しない場合は、Java(TM) Object Serialization Specification

于 2012-09-07T01:21:39.030 に答える
0

@Steve Kuoが述べたように、serialVersionUIDフィールドを持っている必要はありません。

オブジェクトをシリアライズ可能にする契約の一部として強制されていないため、イライラします。私たちのチームの開発者の約半分はそれを行い、残りの半分はそうではありません。通常は設定するだけの大多数private static final long serialVersionUID = 1L;(ただし、一部の開発者は、疑似ランダムLongを思い付く機会としてそれを使用することを好みます...)

そうは言っても、Serializableオブジェクトをバージョン管理するための基本的な試みであると常に理解しています。

私たちが持っているとしましょう:

public class PersonDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    private String firstName;
    private String lastName;

    // Appropriate getters/setters of course
}

その後、新しいフィールドを追加しましたprivate String middleInitial

serialVersionUIDを2に上げる場合は、これを使用してクラスが変更されたことを示すことができます。この変更されたクラス定義では、serialVersionUIDを持つPersonDTOの古いシリアル化済みインスタンスを逆シリアル化できません。

于 2012-09-07T01:27:15.037 に答える