Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 反序列化时,父类(未实现序列化接口)构造函数被调用两次_Java_Serialization_Constructor - Fatal编程技术网

Java 反序列化时,父类(未实现序列化接口)构造函数被调用两次

Java 反序列化时,父类(未实现序列化接口)构造函数被调用两次,java,serialization,constructor,Java,Serialization,Constructor,我定义了两个类,如下所示 public class D{ private String name; public D(){ System.out.println("class D : constructor called !!"); } public String getName(){ return name; } public void setName(String name){ this.

我定义了两个类,如下所示

public class D{

    private String name;

    public D(){
        System.out.println("class D : constructor called !!");
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}

public class E extends D implements Serializable{

    private String name;

    public E(){
        System.out.println("class E : constructor called !!");
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name = name;
    }
}
执行序列化时,它按预期工作,其代码如下:-

public class TestSerialization{

    private static final String FILE_NAME = "E.ser";

    public static void main(String[] args){

        E e = new E();
        e.setName("New Name added");
        writeObject(e);
        E finalE = readObject();
        System.out.println(finalE.getName());

    }

    private static E readObject(){
        E e = null;
        try{
            FileInputStream fis = new FileInputStream(FILE_NAME);
            ObjectInputStream inputStream = new ObjectInputStream(fis);
            e =(E)inputStream.readObject();
            inputStream.close();
        }catch (FileNotFoundException ex){
            System.out.println("Exception : "+ex.getMessage());
        }catch (IOException ex){
            System.out.println("Exception : "+ex.getMessage());
        }catch (ClassNotFoundException ex){
            System.out.println("Exception : "+ex.getMessage());
        }
        return e;
    }

    private static void writeObject(E e){
        try{
            FileOutputStream fos = new FileOutputStream(FILE_NAME);
            ObjectOutputStream outputStream = new ObjectOutputStream(fos);
            outputStream.writeObject(e);
            outputStream.flush();
            outputStream.close();
        }catch (FileNotFoundException ex){
            System.out.println("Exception : "+ex.getMessage());
        }catch (IOException ex){
            System.out.println("Exception : "+ex.getMessage());
        }
    }
}   
在序列化过程中,构造函数链接是正确的:- 输出

但在反序列化过程中有点混乱:- 输出

为什么再次调用D类构造函数

During Serialization Constructor chaining is coming correct :- Output

class D : constructor called !!
class E : constructor called !!
我认为你对这个概念感到困惑或误解了

如果将主类中的代码更改为

public static void main(String[] args){

    E e = new E();
    e.setName("New Name added");

    System.out.println("Serialization Started");
    writeObject(e);

    System.out.println("Deserialization Started");
    E finalE = readObject();
    System.out.println(finalE.getName());

}
您的输出将如下所示

class D : constructor called !!
class E : constructor called !!
Serialization Started
Deserialization Started
class D : constructor called !!
New Name added
因此,您可以在这里看到,在序列化时不会调用E和D的构造函数,但在创建对象E时会调用它

反序列化对象时,不会调用其构造函数,但会调用其父对象的默认构造函数


因此,必须有一个没有所有父类参数的标准构造函数,否则它将抛出异常java.io.InvalidClassException

构造
E
时打印的两条消息被重复计算。这不是反序列化的一部分

public static void main(String[] args){

    E e = new E();
    e.setName("New Name added");

    System.out.println("Serialization Started");
    writeObject(e);

    System.out.println("Deserialization Started");
    E finalE = readObject();
    System.out.println(finalE.getName());

}
class D : constructor called !!
class E : constructor called !!
Serialization Started
Deserialization Started
class D : constructor called !!
New Name added