简体   繁体   English

Java对象序列化和继承

[英]Java object Serialization and inheritance

Say you have these two classes, Foo and Bar where Bar extends Foo and implements Serializable 假设您有这两个类,Foo和Bar,其中Bar扩展了Foo并实现了Serializable

class Foo {

public String name;

public Foo() {
    this.name = "Default";
}

public Foo(String name) {
    this.name = name;
}
}

class Bar extends Foo implements java.io.Serializable {

public int id;

public Bar(String name, int id) {
    super(name);
    this.id = id;
}
}

Notice that Foo doesn't implement Serializable . 请注意,Foo不实现Serializable So what happens when bar is serialized? 那么当条形序列化时会发生什么?

    public static void main(String[] args) throws Exception {

    FileOutputStream fStream=new FileOutputStream("objects.dat");
    ObjectOutputStream oStream=new ObjectOutputStream(fStream);
    Bar bar=new Bar("myName",21);
    oStream.writeObject(bar);

    FileInputStream ifstream = new FileInputStream("objects.dat");
    ObjectInputStream istream = new ObjectInputStream(ifstream);
    Bar bar1 = (Bar) istream.readObject();
    System.out.println(bar1.name + "   " + bar1.id);

} 

it prints "Default 21". 它打印“默认21”。 The question is, why the default constructor get called when the class is not serialized? 问题是,为什么在未对类进行序列化时调用默认构造函数?

Serializable is just a "marker interface" for a given class. Serializable只是给定类的“标记接口”。

But that class must adhere to certain rules: 但该课程必须遵守某些规则:

http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html http://docs.oracle.com/javase/1.5.0/docs/api/java/io/Serializable.html

To allow subtypes of non-serializable classes to be serialized, the subtype may assume responsibility for saving and restoring the state of the supertype's public, protected, and (if accessible) package fields. 为了允许序列化非可序列化类的子类型,子类型可以承担保存和恢复超类型的公共,受保护和(如果可访问)包字段的状态的责任。 The subtype may assume this responsibility only if the class it extends has an accessible no-arg constructor to initialize the class's state. 只有当它扩展的类具有可访问的no-arg构造函数来初始化类的状态时,子类型才可以承担此责任。 It is an error to declare a class Serializable if this is not the case. 如果不是这种情况,则声明类Serializable是错误的。

to answer @Sleiman Jneidi question asked in comment, in oracle documentation mentioned above, its clearly mentioned 回答@Sleiman Jneidi的问题在评论中提到,在上面提到的oracle文档中,它明确提到了

During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. 在反序列化期间,将使用类的public或protected no-arg构造函数初始化非可序列化类的字段。 A no-arg constructor must be accessible to the subclass that is serializable. 必须可以对可序列化的子类访问no-arg构造函数。 The fields of serializable subclasses will be restored from the stream. 可序列化子类的字段将从流中恢复。

Thus, default no-arg constructor of class Foo called of, resulted in initialization. 因此,调用类Foo的默认no-arg构造函数导致初始化。

it may be that the defaultWriteObject can only write the non-static and non-transient fields of the current class . 可能defaultWriteObject只能写入当前类的非静态和非瞬态字段 Once the superclass does not implements the Serializable interface, the fields in the superclass can not be serialized into the stream. 一旦超类不实现Serializable接口,超类中的字段就无法序列化到流中。

实际上当你要读取父类对象时,因为它根本不是序列化的。所以对于非序列化的东西,JVM会经历与我们使用new关键字创建新对象时所用的相同的过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM