java长训_【知了堂学习笔记】浅谈对象的初始化顺序

本文详细探讨了Java中对象初始化的顺序,包括没有继承情况下的静态成员、静态初始化块、成员变量、初始化块和构造方法的执行顺序。在继承场景下,介绍了父类和子类的静态成员、实例成员、初始化块及构造方法的执行流程。此外,还解释了静态初始化块和非静态初始化块的区别,并提供了示例代码和输出结果,帮助理解初始化过程。
摘要由CSDN通过智能技术生成

1.没有继承情况下的初始化顺序

1 packageInitializationOrder;

2 /**

3 * 没有继承的初始化顺序

4 * @author TANJIAYI

5 *

6 */

7 public classTest4 {

8 public static voidmain(String[] args) {

9 newOrder();

10 }

11 }

12 classOrder{

13 AAA s = new AAA("成员变量");

14 static AAA a = new AAA("静态成员变量");

15 {

16 System.out.println("初始化块");

17 }

18 static{

19 System.out.println("静态初始化块");

20 }

21 Order(){

22 System.out.println("构造方法");

23 }

24

25 }

26 classAAA{

27 publicAAA(String str){

28 System.out.println(str);

29 }

30 }

输出结果:

静态成员变量

静态初始化块

成员变量

初始化块

构造方法

结论:在没有继承的条件下,实例化一个对象,构造的先后顺序是,静态成员变量>静态初始化块>成员变量>初始化块>构造方法

一般顺序为 先静态,后非静态,先变量,后初始化块,再是构造方法

2.经典面试题

直接上代码:

1 packageInitializationOrder;

2 /**

3 * 初始化顺序 静态变量 静态初始化块 成员变量 初始化块 构造函数

4 * @author TANJIAYI

5 *

6 */

7 public classTest1 {

8

9 public static Test1 t1 = new Test1("t1");//第1步

10 public static int k = 0;

11 public static Test1 t2 = new Test1("t2");//第2步

12 public static int i = print("i");//第3步

13 public static int n = 99;//第4步

14 public int j = print("j");//第6步

15 {

16 print("构造");//第7步

17 }

18 static{

19 print("静态");//第5步

20 }

21 publicTest1(String str){

22 System.out.println((++k)+":"+str+" i="+i+" n="+n);

23 ++i;

24 ++n;

25 }

26 private static intprint(String str) {

27 System.out.println((++k)+":"+str+" i="+i+" n="+n);//1:j i=0 n=0

28 ++n;

29 return ++i;

30 }

31 public static voidmain(String[] args) {

32 Test1 test = new Test1("init");//第8步

33 }

34 }

输出结果为:

1:j  i=0 n=0

2:构造  i=1 n=1

3:t1  i=2 n=2

1:j  i=3 n=3

2:构造  i=4 n=4

3:t2  i=5 n=5

4:i  i=6 n=6

5:静态  i=7 n=99

6:j  i=8 n=100

7:构造  i=9 n=101

8:init  i=10 n=102

解题思路:

(1)   按照对象初始化顺序依次执行,首先静态变量从代码中的第九行到第13行依次执行。

(2)   执行第1步,调用new Test1()方法,本方法是个构造方法,在执行前,类加载的时候先把k,i和n的值加载进来,初始值为0,接着执行第14行成员变量j;调用print()方法,把j赋给str,所以27行代码打印第一条输出:1:j i=0 n=0,在执行初始化块,15—17行,打印出2:构造 i=1 n=1,最后在执行Test1()构造方法,打印出  3:t1 i=2 n=2,第1步语句执行完毕,接着执行第2步。

(3)   分析同上,逐步打印出答案。

为了好理解,下面附上一张图,挨着挨着看思路还是很清楚的哦!图画得有点儿乱:

e031cfd04dc812169e0bea83930b5940.png

总结:大家只要掌握好执行的先后顺序,仔细分析题,就没有问题。

2.继承情况下对象的初始化顺序

属性、方法、构造方法和自由块都是类中的成员,在创建类的对象时,类中各成员的执行顺序:

1.父类静态成员和静态初始化快,按在代码中出现的顺序依次执行。

2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。

3. 父类的实例成员和实例初始化块,按在代码中出现的顺序依次执行。

4. 执行父类的构造方法。

5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。

6.执行子类的构造方法。

1 packageInitializationOrder;2 /**

3 * 继承下的初始化顺序4 *@authorTANJIAYI5 *6 */

7 public classTest2 {8 public static voidmain(String[] args) {9 newSon();10 }11 }12 classParent{13

14 {15 System.out.println("parent中的初始化块");16 }17 static{18 System.out.println("parent中static初始化块");19 }20

21 publicParent(){22 System.out.println("parent构造方法");23 }24 }25

26 class Son extendsParent{27 {28 System.out.println("son中的初始化块");29 }30

31 static{32 System.out.println("son中的static初始化块");33 }34

35 publicSon(){36 System.out.println("son构造方法");37 }38 }

输出结果:

15e0c74f5e36e03cd5e7b850a63588c9.png

初始化块主要用于对象的初始化操作,在创建对象时调用,可以用于完成初始化属性值、加载其他的类的功能。

初始化块和构造方法功能类似,可以再创建对象的时候完成一些初始化的操作,一般的情况下,构造方法初始化和初始化块初始化可以通用。

构造方法在初始化的时候可以通过参数传递,但是初始化块不能,初始化块的初始化在构造方法之前执行,如果搞糟方法多次重载,此时可以考虑构造方法中共通的代码放到初始化块中进行初始化。

补充:

静态初始化块和非静态初始化块的区别?

非静态初始化块主要是用于对象的初始化操作,在每次创建对象的时都要调用一次,其执行顺序在构造方法之前。

在初始化块之前有static修饰,则为静态初始化块。由于非静态成员不能再静态方法中使用,同样也不能在静态初始化块中,因此,静态初始化块主要用于初始化静态变量和静态方法,静态初始化块只调用一次,是在类的第一次加载到内存时,并非一定要创建对象才执行。

静态初始化块比非静态初始化块先执行

知了堂:www.zhiliaotang.com

写得比较随意,很多地方,很不完全,希望广大的友友们,发现问题,给我留言,指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值