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

时间:2012-02-04 16:45:58

标签: java serializable

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

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

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

6 个答案:

答案 0 :(得分:19)

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

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

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

答案 1 :(得分: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

答案 2 :(得分:8)

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

答案 3 :(得分:7)

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

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

  

强烈建议显式serialVersionUID   声明尽可能使用私有修饰符,因为这样   声明仅适用于立即声明   class - serialVersionUID字段作为继承成员无用。

答案 4 :(得分:3)

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

答案 5 :(得分:3)

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

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