java - 带继承的序列化 (Java)

标签 java inheritance serialization constructor deserialization

我正在学习序列化和继承,但我不明白谁在反序列化过程中调用无参数构造函数。父类(super class) A 没有实现 Serialized,子类 B 扩展了 A 实现了 Serializable。

父类(super class)A

public class A {

    int i;

    public A(int i) 
    {
        this.i = i;
    }

    public A()
    {
        i = 50;
        System.out.println("A's class constructor called");
    }  
}

子类B

import java.io.Serializable;

public class B extends A implements Serializable {

    int j;

    // parameterized constructor
    public B(int i,int j) 
    {
        super(i);
        this.j = j;
    }
}

驱动程序类别

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class Test {

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

        B b1 = new B(10,20);

        System.out.println("i = " + b1.i);
        System.out.println("j = " + b1.j);

        // Serializing B's(subclass) object 

        //Saving of object in a file
        FileOutputStream fos = new FileOutputStream("abc.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        // Method for serialization of B's class object
        oos.writeObject(b1);

        // closing streams
        oos.close();
        fos.close();

        System.out.println("Object has been serialized");

        // De-Serializing B's(subclass) object 

        // Reading the object from a file
        FileInputStream fis = new FileInputStream("abc.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);

        // Method for de-serialization of B's class object
        B b2 = (B)ois.readObject();  // The A() constructor is called here

        // closing streams
        ois.close();
        fis.close();

        System.out.println("Object has been deserialized");

        System.out.println("i = " + b2.i);
        System.out.println("j = " + b2.j);
    }
}

如果我删除 A() 构造函数,则会收到 InvalidClassException。我看到创建 b2 对象时调用了 A(),但我不明白为什么在此语句中调用此 A() 以及调用它的人。

创建 b1 对象时,将调用 B(int i, int j) 构造函数和 A(int i) 构造函数。这很容易理解。但我不明白为什么在创建 b2 对象时调用 A() 构造函数。

最佳答案

来自Serializable JavaDocs :

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. It is an error to declare a class Serializable if this is not the case. The error will be detected at runtime.

现在回答你的问题:

If I delete the A() constructor I get the InvalidClassException. I see that A() is called when the b2 object is created but I don't understand why this A() is called at this statement and who called it.

A() 构造函数由序列化机制通过反射调用。具体来自 ObjectInputStream 通过 ObjectStreamClass

关于java - 带继承的序列化 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49842861/

相关文章:

c++ - 在 Boost 序列化中展平嵌套的命名值对

java - 使用 Spring Data JPA 更新实体的正确方法是什么?

java - 在 CLASSPATH 中具有 Jar 的终端中编译 Java 代码

Java:突出显示所有派生数据成员

C++ 继承错误 : ambiguous error

scala - 特征和序列化/反序列化

c# - byte[] 到 ArrayList?

java - 我需要在java中制作一个有两个选择的下拉框

java - Spring Mongodb查询DbRef(一对多关系)

c++ - 如何构建接收引用参数的基类?