Java继承类的初始化先后顺序

       在类的继承中,初始化的顺序决定着程序的输出。一般而言,类的代码在第一次使用时才加载。下面通过代码和输出分析类初始化顺序。

 

class GrandParent {
    int i = 9;
    int j;
    static int x1 = prt("static GrandParent.x1 initialized");//注意这里是static字段
    
    static{
    <span style="white-space:pre">	</span>System.out.println("GrandParent");
    }
    GrandParent() {
        prt("i = " + i + ", j = " + j);
        j = 39;
    }
    static int prt(String s) {
    <span style="white-space:pre">	</span>System.out.println(s);
        return 30;
    }


}
class Parent extends GrandParent {
    static int x1 = prt("static Parent.x1 initialized");//注意这里是static字段
    
    static{
    <span style="white-space:pre">	</span>System.out.println("parent");
    }
    Parent() {
        prt("i = " + i + ", j = " + j);
        j = 55;
    }


    static int prt(String s) {
    <span style="white-space:pre">	</span>System.out.println(s);
        return 47;
    }


}


public class Son extends Parent {
    int k = prt("Son.k initialized");
    static{
    <span style="white-space:pre">	</span>System.out.println("son");
    }
    static int x1 = prt("static Son.x1 initialized");//注意这里是static字段
    
    Son() {
        prt("k = " + k + ", j = " + j);
        }
    
    static int prt(String s) {
        System.out.println(s);
        return 63;
    }


    public static void main(String[] args) {
        prt("Son constructor");
        Son s = new Son();
        System.out.println(x1);
    }
}

 

 

输出结果:

 

 

static GrandParent.x1 initialized
GrandParent
static Parent.x1 initialized
parent
son
static Son.x1 initialized
Son constructor
i = 9, j = 0
i = 9, j = 39
Son.k initialized
k = 63, j = 55
63

 

结果分析:

我们知道程序运行的入口是public static void main(String[] args)。存在static属性和static代码块时,先不执行main函数的第一条程序,而是进行static初始化。在初始化时,先初始化基类,再初始化子类。因此,static初始化(static属性和static代码块优先级相同,谁在前先初始化谁),按照基类到子类的顺序,得到前部分输出:

static GrandParent.x1 initialized
GrandParent
static Parent.x1 initialized
parent
son
static Son.x1 initialized

static初始化完成后,执行main函数的第一条程序 prt("Son constructor"),输出:

 

 

Son constructor

接着执行第二条程序Son s = new Son(),创建Son对象,Son的基类为Parent,Parent的基类为GrandParent,因此首先要完成GrandParent类的初始化,按照普通类初始化的顺序,先初始化属性,再初始化构造器(static已经在前面初始化了),完成GrandParent类的初始化得到输出:

 

 

i = 9, j = 0

同理,完成Parent类的初始化得到输出:

 

 

i = 9, j = 39

继续同理,完成Son类的初始化得到输出:

 

 

 

 

Son.k initialized
k = 63, j = 55

执行第三条程序System.out.println(x1),因为最后执行Son类的prt(String s)方法,返回值为63,所以输出:

 

 

63

 

Java继承类的初始化先后顺序总结:

       先进行static初始化(static属性和static代码块谁在前先初始化谁),接着执行main方法中的程序,从上到下依次执行。执行到创建对象的语句时,先完成基类的初始化,此时将基类看成普通类,按照普通类的初始化原则(先初始化属性,再初始化构造器,因为static已经在前面初始化了),同理进行子类的初始化。

PS:想说清楚,说的有点啰嗦,希望大家谅解哈。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值