static同构造函数的执行顺序

本文详细解析了Java中构造函数的调用顺序,通过两个示例演示了子类构造时父类构造函数如何被调用,以及静态成员和实例成员的初始化过程。

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

例1:
abstract class Glyph {
2 Glyph() {
3 System.out.println( " Glyph() before draw() " );
4 draw(); // 不明白的地方是这里.
5 System.out.println( " Glyph() after draw() " );
6 }
7 abstract void draw();
8 }
9
10 class RoundGlyph extends Glyph {
11 private int radius = 1 ;
12 RoundGlyph( int r) {
13 radius = r;
14 System.out.println( " RoundGlyph.RoundGlyph(), radius = " + radius);
15 }
16
17 void draw() {
18 // radius = z;
19 System.out.println( " RoundGlyph.draw(), radius = " + radius);
20 }
21 }
22
23 public class PolyConstructors {
24 public static void main(String[] args) {
25 new RoundGlyph( 5 );
26 }
27 }

答案:
1 Glyph() before draw()
2 RoundGlyph.draw(), radius = 0
3 Glyph() after draw()
4 RoundGlyph.RoundGlyph(), radius = 5
分析:分析
1类初始化时构造函数调用顺序:
2 首先加载类,遇到extends字样会停止加载当前类,加载父类,之后再继续加载。
3 当把一个类完全加载后,这个类的静态成员将被先加载。之后进行如下流程:
4(1)初始化对象的存储空间为零或null值;
5(2)调用父类构造函数;
6(3)按顺序分别调用类成员变量和实例成员变量的初始化表达式;
7(4)调用本身构造函数
8
9构造函数的初始化顺序:
101 .当执行new RoundGlyph( 5 )时,首先会加载‘RoundGlyph. class ’,但是这个时候JVM发现 RoundGlyph extends (继承于) Glyph ,所以他会加载Glyph. class
112 .然后会初始化Glyph类的static成员数据,这个类没有static成员数据,所以没有这一步。
123 .会执行Glyph类的构造函数Glyph()
134 .接着初始化RoundGlyph类的成员数据,最后调用RoundGlyph()构造函数来生产对象
例2:
1public class Test2 extends Test1 {
2 {
3 System.out.print( " 1 " );
4 }
5 Test2() {
6 System.out.print( " 2 " );
7 }
8 static {
9 System.out.print( " 3 " );
10 }
11 {
12 System.out.print( " 4 " );
13 }
14 public static void main(String[] args) {
15 new Test2();
16 }
17}
18
19class Test1 {
20 Test1() {
21 System.out.print( " 5 " );
22 }
23 static {
24 System.out.print( " 6 " );
25 }
26}
答案:635142
解析: 1( 1 ) 虚拟机试图加载Test2,其父类为Test1
2 ( 2 ) 虚拟机加载Test1
3 ( 3 ) Test1静态初始化 -----> 输出 " 6 "
4 ( 4 ) 虚拟机加载Test2
5 ( 3 ) Test2静态初始化 -----> 输出 " 3 "
6 ( 5 ) new Test2()构造Test2首先构造父类Test1
7 ( 6 ) Test1构造 -----> 输出 " 5 "
8 ( 7 ) Test2执行初始化语句块(虚拟机调用Test2初始化方法init) -----> 输出 " 1 " 和 " 4 "
9 ( 8 ) Test2构造 -----> 输出 " 2 "
10
11 =================================
12 先输出6:
13 因为父类的Static的变量 / 常量会被子类共享
14 所以,首先输出6
15 接着,会先初始化自身的static的变量 / 常量
16
17 然后,在构造函数中,会首先调用父类的默认构造函数(如果没有显示调用super(args)的话)
18 在调用父类构造函数时,在执行构造函数体中的数据内容时,先执行方法外的程序段,如变量申明,或者程序段。然后再调用构造函数中的程序段。
19 然后再执行自身的构造函数,执行前,也如上述说:在执行本构造函数体中的数据内容时,先执行方法外的程序段,如变量申明,或者程序段。然后再调用构造函数中的程序段。
20
21 这就是一个对象的实例化过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值