Ответ 1
Да. Подкласс не обязательно должен быть помечен как сериализуемый.
и отметка id как protected
будет выполнена. (с точки зрения компилятора)
Но, как хорошая практика, каждый класс должен иметь свой собственный serialVersionUid
Если у меня есть B расширяет A... и A реализует Serializable, мне нужно написать "B реализует Serializable"?
Я думаю, нет, но я хотел бы подтвердить...
также, если я поместил идентификатор сериализации в A... мне тоже нужно поставить его в B? должен ли идентификатор сериализации в быть защищенным (не закрытым)?
Да. Подкласс не обязательно должен быть помечен как сериализуемый.
и отметка id как protected
будет выполнена. (с точки зрения компилятора)
Но, как хорошая практика, каждый класс должен иметь свой собственный serialVersionUid
Знак идентификации как защищенный будет достаточным с точки зрения компилятора. Однако теоретически точка поля serialVersionUID
в классе Serializable
заключается в том, чтобы легко отличать "версии" класса при десериализации - четко обозначать, когда данный объект можно десериализовать в экземпляр предоставленного class (если serialVersionUID
разные, генерируется исключение). Если вы хотите четко проследить версии и характер объекта, объявите serialVersionUID
для каждого подкласса.
Вам не нужно явно отмечать производный как 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 унаследовано от a: 1
a используется сериализацией: 1
b, используемый сериализацией: -3675232183873847366
В моем согласии с @azodious ответом дочерний класс наследует сериализуемые свойства родительского класса, но вам придется объявить serialVersionUID явно.
Из документов Java: https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html
Также настоятельно рекомендуется, чтобы явный serialVersionUID декларации используют, по возможности, частный модификатор, поскольку такие декларации применяются только к немедленному объявлению class - serialVersionUID не полезны как унаследованные.
Нет, потому что B уже реализует его через свой базовый класс A. То, что наследует все.
Объект Java является сериализуемым, если его класс или любой из его суперклассов реализует либо интерфейс java.io.Serializable, либо его subinterface, java.io.Externalizable.
Вы можете посмотреть официальную документацию и найти ее там: https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html