Если мой класс реализует Serializable, должен ли я реализовать его в его подклассах? - PullRequest
30 голосов
/ 04 февраля 2012

Если у меня B расширяет A ... и A реализует Serializable, нужно ли мне писать "B реализует Serializable"?

Я думаю, нет, но мне нужно подтверждение ...

также, если я помещаю идентификатор сериализации в A ... мне нужно также поместить один в B?должен ли идентификатор сериализации в A быть защищенным (не частным)?

Ответы [ 6 ]

19 голосов
/ 04 февраля 2012

Да. Подкласс не должен быть помечен как сериализуемый явно.

И, пометив id как protected (с точки зрения компилятора).

Но в качестве хорошей практики каждый класс должен иметь свой собственный serialVersionUID.

12 голосов
/ 23 июля 2015

Вам не нужно явно отмечать производное как 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:

b унаследовано от: 1

используется для сериализации: 1

b используется при сериализации: -3675232183873847366

8 голосов
/ 04 февраля 2012

Пометка идентификатора как защищенного будет достаточной с точки зрения компилятора.Однако, теоретически, цель поля serialVersionUID в классе Serializable состоит в том, чтобы легко различать «версии» класса при десериализации его - четко обозначить, когда данный объект может быть десериализован в экземпляркласс (если serialVersionUID отличаются, генерируется исключение).Если вы хотите иметь возможность четко отслеживать версии и характер объекта, объявите serialVersionUID для каждого подкласса.

7 голосов
/ 13 декабря 2013

В моем согласии с ответом @azodious дочерний класс наследует сериализуемые свойства родительского класса, но вам придется явно объявить serialVersionUID .

Из документов Java: https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html

Также настоятельно рекомендуется, чтобы явный serialVersionUID объявления используют частный модификатор, где это возможно, так как такие декларации применяются только к немедленному декларированию class - поля serialVersionUID не используются как унаследованные члены.

3 голосов
/ 23 февраля 2017

Объект Java сериализуем, если его класс или любой из его суперклассов реализует интерфейс java.io.Serializable или его подынтерфейс java.io.Externalizable.

Вы можете взглянуть на официальную документацию инайди это там: https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html

3 голосов
/ 04 февраля 2012

Нет, потому что B уже реализует его через свой базовый класс A. В этом и заключается наследование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...