web-dev-qa-db-ja.com

クラスがSerializableを実装している場合、そのサブクラスに実装する必要がありますか?

BがAを拡張し、AがSerializableを実装している場合、「BimplementsSerializable」と書く必要がありますか?

いいえと思いますが、確認をお願いします...

また、シリアル化IDをAに入れると... Bにも入れる必要がありますか? Aのシリアル化IDを保護する必要がありますか(プライベートではありません)?

32
ycomp

はい。サブクラスを明示的にシリアル化可能としてマークする必要はありません。

また、idをprotectedとしてマークすると、(コンパイラーの観点から)機能します。

ただし、グッドプラクティスとして、すべてのクラスに独自のプライベートserialVersionUIDが必要です。

19
Azodious

派生をSerializableとして明示的にマークする必要はなく、継承されます。ただし、親からのserialVersionUIDは継承されますが、シリアル化プロセスでは使用されません。子にserialVersionUIDを追加しない場合、子が生成されます。

下記参照:

public class A implements Serializable {
    protected static final long serialVersionUID = 1L;
}

public class B extends A {
}

public class Main {

    public static void main(String[] args){

        A a = new A();
        B b = new B();

        Class aClass = a.getClass();
        Class bClass = b.getClass();

        long aUid = ObjectStreamClass.lookup(aClass).getSerialVersionUID();
        long bUid = ObjectStreamClass.lookup(bClass).getSerialVersionUID();

        System.out.printf("serialVersionUID:\n");
        System.out.printf("b inherited from a: %d\n", b.serialVersionUID);
        System.out.printf("a used by serialization: %d\n",aUid);
        System.out.printf("b used by serialization: %d\n",bUid);
    }

}

出力:

serialVersionUID:

aから継承されたb:1

シリアル化で使用される:1

bシリアル化で使用:-3675232183873847366

12
Howard Swope

コンパイラの観点からは、idを保護済みとしてマークするだけで十分です。ただし、理論的には、serialVersionUIDクラスのSerializableフィールドのポイントは、クラスを逆シリアル化するときにクラスの「バージョン」を簡単に区別することです。つまり、特定のオブジェクトをいつ逆シリアル化できるかを明確に示すことです。提供されたクラスのインスタンスに(serialVersionUIDsが異なる場合、例外がスローされます)。オブジェクトのバージョンと性質を明確に追跡できるようにする場合は、各サブクラスでserialVersionUIDを宣言します。

8
Jim Kiley

@azodiousの回答への私の同意では、子クラスは親クラスのシリアル化可能なプロパティを継承しますが、serialVersionUIDを明示的に宣言する必要があります。

From Java docs: https://docs.Oracle.com/javase/8/docs/api/Java/io/Serializable.html

また、明示的なserialVersionUID宣言では、可能な場合はプライベート修飾子を使用することを強くお勧めします。このような宣言は、すぐに宣言するクラスにのみ適用されるためです。serialVersionUIDフィールドは、継承されたメンバーとしては役立ちません。

7
vsingh

いいえ、Bはすでに基本クラスAを介して実装しているためです。これが、継承のすべてです。

3
Lucius

Javaオブジェクトは、そのクラスまたはそのスーパークラスのいずれかがJava.io.SerializableインターフェイスまたはそのサブインターフェイスJava.io.Externalizableのいずれかを実装している場合にシリアル化可能です。

公式ドキュメントを見て、ここで見つけることができます: https://docs.Oracle.com/javase/tutorial/jndi/objects/serial.html

3
minotna