java文件传输基础:序列化中子类和父类构造函数的调用问题

探讨了Java中对象序列化过程中,父类与子类实现Serializable接口时构造函数的调用规则,并通过实例解释了不同情况下构造函数是否被显式调用的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    前面我们学习了对象序列化的知识,那么在对象的序列化中,子类和父类实现序列化接口和其构造函数调用规则是什么呢?我们直接通过一段代码来测试一下:

class Father implements Serializable{
    public Father() {
 System.out.println("这是父类");        
    }
}
class Son extends Father{
    public Son() {
        System.out.println("这是子类");
    }
}

class Sonson extends Son{
    public Sonson() {
        System.out.println("这是子类的子类");
    }
}

首先我们完成三个类之间的继承关系,Father->Son->Sonson,我们在Father类中实现序列化接口,接下来进行测试,看看每个类的构造函数调用情况:

ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D:\\log_network.txt"));
Sonson son=new Sonson();
oos.writeObject(son);
oos.flush();
oos.close();

首先对Sonson对象进行序列化,其次进行反序列化输出对象:

ObjectInputStream ois=new ObjectInputStream(new FileInputStream("D:\\log_network.txt"));
        Sonson son=(Sonson) ois.readObject();
        System.out.println(son);
        ois.close();

得到测试结果:
com.objectserialize.Sonson@1b28cdfa
发现该子类的直接父类Sonson以及间接父类Father的构造函数并没有被显式调用

那如果把序列化接口放在子类呢?

class Bar{
    public Bar() {
        System.out.println("bar");
    }
}
 class Bar1 extends Bar{
     public Bar1() {
         System.out.println("Bar1");
     }
 }
 class Bar2 extends Bar1  implements Serializable{
     public Bar2() {
         System.out.println("Bar2");
     }
 }

这是序列化接口在子类Bar2中得以实现,再次进行测试,序列化:

ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("D:\\log_network.txt"));
Bar2 son=new Bar2();
oos.writeObject(son);
oos.flush();
oos.close();

反序列化:

ObjectInputStream ois=new ObjectInputStream(new FileInputStream("D:\\log_network.txt"));
Bar2 son=(Bar2) ois.readObject();
System.out.println(son);
ois.close();

测试结果为:
bar
Bar1
com.objectserialize.Bar2@e9e54c2

测试结果显示,当父类没有实现序列化接口时,被显式调用

那么,为什么父类实现序列化接口后,子类的构造函数就不会被显式调用?
    我们将序列化的对象写入文件中,由于父类实现了序列化接口,父类对象已经保存到了文件中,在反序列化的过程中,java要构造一个对象,首先要构造其父类对象,由于父类被保存在了文件里,因此不需要再进行显式调用父类的构造函数,而子类继承了父类的序列化接口,因此子类的构造函数也不会被显式调用
子类实现了序列化接口,为什么会调用父类的构造函数呢?
    我们将子类对象进行序列化时,由于子类实现了序列化接口而父类并没有,则父类对象也就不会被序列化,因此父类对象没有被保存在文件中,在反序列化的过程中,由于子类对象已经被保存到了文件中,因此子类对象的构造函数不会被显式调用。而父类对象没有被保存,在构造父类对象时需要调用父类对象的构造函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值