Java 构造方法的继承/构造方法的调用顺序(二)

我们在构造方法的继承、调用顺序(一)一文中,已经了解过子类的构造过程中,构造方法是如何调用的。

那么,我们看下面一个例子来巩固一下:

package com.company;


public class Main {
    public static void main(String[] args) {
        new B(6); //B类型实例化,会调用到B类型的构造函数
    }

    public static class A {
        private int f1 = 7;                 //(1)

        public A(int b) {                   //(A())
            this.f1 = b;			        //(2)
            System.out.println("step1");    //(3)
            initialize();			        //(4)
        }

        protected void initialize() {       //(5)
            System.out.println("step2");
            System.out.println(f1);
        }
    }

    public static class B extends A {   // B是A的子类,所以才能在B的构造方法中调用A的构造方法
        protected int f1 = 3;              //(6)

        public B(int f1) {   //B类型实例化,会调用到B类型的构造方法
            super(f1);       //(7)
            this.f1 += f1;   //(8)
            initialize();    //(9) 
        }

        protected void initialize() {      //(10)
            System.out.println("step3");
            System.out.println(f1);
        }
    }
}

输出:

step1
step3
0
step3
9

在上面的代码中,new B(6) 对子类B进行实例化,
new B(6) ---->super(6) ,但是这个时候并没有对B类的成员B.f1初始化,
这是为什么呢?
这是因为B的父类A还未完成构造,jvm会先对父类A进行构造,包括对A.f1初始化 —> A,构造()两个步骤,
在A的构造方法中,调用了initialize(),这个initialize是 B.initialize(),
这是因为A.initialize在此处被B.initialize()所重写,如果将A.initialize修改为private,那么这个重写将不成功(编译不会报错)。

那么这个调用顺序如下;
new B(6) ——> (7)super(f1)检查到B有父类A,进入父类A的构造过程 ——>
——> (1) A.f1初始化 ——> A.A() ——>{(2)(3)(4)——>(10) --(7)完成}
——> 进入子类B的构造过程 ——>
——>(6) B.f1初始化 ——>(8) (此刻B.f1已被初始化) ——>(9)——>(10)。

A.initialize被重写,会导致调用顺序发生变化,为了验证这个问题,我们将上面A类中的代码修改一下:

public static void initialize() {       //(5)

编译报错:
Error:(33, 24) java: com.company.Main.B中的initialize()无法覆盖com.company.Main.A中的initialize()
被覆盖的方法为static

我们将代码再次修改,验证:
修改A类中的代码回原样:

protected  void initialize() {       //(5)

修改B类中的代码:

private void initialize() {      //(10)

再次验证,发现(4)处调用的是A.initialize(),而不是B.initialize,
这是因为B虽然对A的initialize进行了重写,但是由于B中initialize使用了private限定,导致在A类中无法访问B.initialize,最后jvm仍然调用了A的initialize。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值