java实例化调用_Java类加载及实例化的调用顺序

标题起得略拗口,大概意思就是说在一个Java类中,域和构造方法的调用顺序。

1. 没有继承的情况

单独一个类的场景下,初始化顺序为依次为 静态数据,继承的基类的构造函数,成员变量,被调用的构造函数。

其中静态数据只会初始化一次。

packagecom.khlin.binding.test;public classApp2 {public static voidmain(String[] args) {

Son son= newSon();

}

}classSon {publicSon() {

System.out.println("this is son.");

}public Son(intage) {

System.out.println("son is " + age + " years old.");

}private Height height = new Height(1.8f);public static Gender gender = new Gender(true);

}classHeight {public Height(floatheight) {

System.out.println("initializing height " + height + " meters.");

}

}classGender {public Gender(booleanisMale) {if(isMale) {

System.out.println("this is a male.");

}else{

System.out.println("this is a female.");

}

}

}

输出:

c4f297a64e32e1f47144039a9d243c3f.png

2. 继承的情况

稍微修改一下代码,添加两个基类,让Son继承Father, Father继承Grandpa。

继承的情况就比较复杂了。由于继承了基类,还将往上回溯,递归地调用基类的无参构造方法。

在我们的例子中,在初始化静态数据后,会先往上追溯,调用Father的默认构造方法,此时再往上追溯到Grandpa的默认构造方法。

注:如果在子类的构造方法中,显式地调用了父类的带参构造方法,那么JVM将调用指定的构造方法而非默认构造方法。

基类和子类均有静态数据,成员变量和构造方法的场景

我们继续修改代码,让其最终呈现如下:

1 packagecom.khlin.binding.test;2

3 public classApp2 {4 public static voidmain(String[] args) {5 Son son = newSon();6 }7 }8

9 classGrandpa {10 publicGrandpa() {11 System.out.println("this is grandpa.");12 }13

14 public Grandpa(intage) {15 System.out.println("grandpa is " + age + " years old.");16 }17

18 private Height height = new Height(1.5f);19

20 public static Gender gender = new Gender(true, "grandpa");21 }22

23 class Father extendsGrandpa {24

25 publicFather() {26 System.out.println("this is father.");27 }28

29 public Father(intage) {30 System.out.println("father is " + age + " years old.");31 }32

33 private Height height = new Height(1.6f);34

35 public static Gender gender = new Gender(true, "father");36 }37

38 class Son extendsFather {39

40 publicSon() {41 super(50);42 System.out.println("this is son.");43 }44

45 public Son(intage) {46 System.out.println("son is " + age + " years old.");47 }48

49 private Height height = new Height(1.8f);50

51 public static Gender gender = new Gender(true, "son");52 }53

54 classHeight {55 public Height(floatheight) {56 System.out.println("initializing height " + height + " meters.");57 }58 }59

60 classGender {61 public Gender(booleanisMale) {62 if(isMale) {63 System.out.println("this is a male.");64 } else{65 System.out.println("this is a female.");66 }67 }68

69 public Gender(booleanisMale, String identify) {70 if(isMale) {71 System.out.println(identify + " is a male.");72 } else{73 System.out.println(identify + " is a female.");74 }75 }76 }

最后输出会是什么呢?

944dcff216259e53803dd8d43401e850.png

在我们的示例中,加载顺序应该是这样的:

Grandpa 静态数据

Father 静态数据

Son 静态数据

Grandpa 成员变量

Grandpa 构造方法

Father 成员变量

Father 构造方法

Son 成员变量

Son 构造方法

所以输出如下:

a41ed37caa95e0102d0648f64f53607e.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值