如果我的类实现了Serializable,我是否必须在其子类中实现它?

问题描述 投票:30回答:6

如果我有B扩展A ...并且A实现了Serializable,我是否必须编写“B implements Serializable”?

我想不,但我想确认......

如果我把序列化ID放在A ...我也需要在B中放一个吗? A中的序列化ID应该受保护(非私有)吗?

java serializable
6个回答
19
投票

是。子类不需要明确标记为可序列化。

并且,将id标记为protected(从编译器角度来看)。

但是,作为良好的做法,每个班级都应该拥有自己的私人serialVersionUID


12
投票

您不必将派生的显式标记为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

a序列化使用:1

b序列化使用:-3675232183873847366


8
投票

从编译器的角度来看,将id标记为受保护就足够了。然而,理论上,serialVersionUID类的Serializable字段的重点是在反序列化时容易区分类的“版本” - 清楚地表示何时可以将给定对象反序列化为所提供类的实例(如果serialVersionUIDs不同,抛出异常)。如果您希望能够清楚地跟踪对象的版本和性质,请在每个子类上声明serialVersionUID


7
投票

在我对@azodious回答的同意中,子类继承了父类的可序列化属性,但是您必须显式声明serialVersionUID。

来自Java文档:https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html

强烈建议显式serialVersionUID声明尽可能使用private修饰符,因为此类声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员无用。


3
投票

不,因为B已经通过它的基类A实现了它。这就是继承的全部意义所在。


3
投票

如果Java对象的类或其任何超类实现java.io.Serializable接口或其子接口java.io.Externalizable,则该对象是可序列化的。

您可以查看官方文档并在那里找到:https://docs.oracle.com/javase/tutorial/jndi/objects/serial.html

© www.soinside.com 2019 - 2024. All rights reserved.