java 执行顺序混乱_Java:请问这段代码的执行顺序是怎么样的,如果能够详细点更好,谢谢...

题主可以通过编译后的class文件反编译来帮助理解初始化过程。

在命令行中的指令javap -l -c -p -v App,执行后就会得到反编译后的内容,下面结合题主给的源码简单分析一下:

下面展示和初始化有关的部分反编译内容

App的class文件

private static com.real.test.App d;

descriptor: Lcom/real/test/App;

flags: ACC_PRIVATE, ACC_STATIC

private com.real.test.SubClass t;

descriptor: Lcom/real/test/SubClass;

flags: ACC_PRIVATE

static {};

descriptor: ()V

flags: ACC_STATIC

Code:

stack=2, locals=0, args_size=0

0: new #1 // class com/real/test/App

3: dup

4: invokespecial #12 // Method "":()V **调用App的构造函数**

7: putstatic #15 // Field d:Lcom/real/test/App;

10: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;

13: iconst_3 **得到数字常量3**

14: invokevirtual #23 // Method java/io/PrintStream.println:(I)V **打印数字常量3**

17: return

LineNumberTable:

line 4: 0

line 8: 10

line 3: 17

LocalVariableTable:

Start Length Slot Name Signature

com.real.test.App(); **构造函数详细内容**

descriptor: ()V

flags:

Code:

stack=3, locals=1, args_size=1

0: aload_0

1: invokespecial #31 // Method java/lang/Object."":()V **调用Object的构造函数**

4: aload_0

5: new #32 // class com/real/test/SubClass

8: dup

9: invokespecial #34 // Method com/real/test/SubClass."":()V **调用SubClass的构造函数**

12: putfield #35 // Field t:Lcom/real/test/SubClass;

15: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;

18: iconst_4 **得到数字常量4**

19: invokevirtual #23 // Method java/io/PrintStream.println:(I)V **打印数字常量4**

22: return

LineNumberTable:

line 11: 0

line 5: 4

line 12: 15

line 13: 22

LocalVariableTable:

Start Length Slot Name Signature

0 23 0 this Lcom/real/test/App;

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=1, args_size=1

0: getstatic #17 // Field java/lang/System.out:Ljava/io/PrintStream;

3: ldc #40 // String Hello **得到字符串Hello**

5: invokevirtual #42 // Method java/io/PrintStream.println:(Ljava/lang/String **打印字符串**

8: return

LineNumberTable:

line 16: 0

line 17: 8

LocalVariableTable:

Start Length Slot Name Signature

0 9 0 args [Ljava/lang/String;

SubClass的class文件

static {}; **静态块**

descriptor: ()V

flags: ACC_STATIC

Code:

stack=2, locals=0, args_size=0

0: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;

3: iconst_1 **得到数字常量1**

4: invokevirtual #14 // Method java/io/PrintStream.println:(I)V **打印数字常量1**

7: return

LineNumberTable:

line 28: 0

line 26: 7

LocalVariableTable:

Start Length Slot Name Signature

public com.real.test.SubClass(); **构造函数**

descriptor: ()V

flags: ACC_PUBLIC

Code:

stack=2, locals=1, args_size=1

0: aload_0

1: invokespecial #23 // Method com/real/test/SuperClass."":()V **调用SuperClass的构造函数**

4: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;

7: iconst_2 **得到数字常量2**

8: invokevirtual #14 // Method java/io/PrintStream.println:(I)V **打印数字常量2**

11: return

LineNumberTable:

line 31: 0

line 32: 4

line 33: 11

LocalVariableTable:

Start Length Slot Name Signature

0 12 0 this Lcom/real/test/SubClass;

SuperClass的class文件

com.real.test.SuperClass();

descriptor: ()V

flags:

Code:

stack=2, locals=1, args_size=1

0: aload_0

1: invokespecial #8 // Method java/lang/Object."":()V **Object的构造函数**

4: getstatic #10 // Field java/lang/System.out:Ljava/io/PrintStream;

7: ldc #16 // String 构造SuperClass **得到字符串构造SuperClass**

9: invokevirtual #18 // Method java/io/PrintStream.println:(Ljava/lang/String;)V **打印字符串**

12: return

LineNumberTable:

line 21: 0

line 22: 4

line 23: 12

LocalVariableTable:

Start Length Slot Name Signature

0 13 0 this Lcom/real/test/SuperClass;

大致解释一下内容(如果题主对JVM指令集感兴趣可以看看JVM规范,里面有很详细的解释)。

上面反编译内容中星号部分是我加上的注解。按照代码的执行顺序:

1.JVM加载App类,App中的静态变量在这时会初始化,对应App中调用App的构造函数的字节码

2.跳到App的构造函数,先初始化父类Object,对应App中调用Object的构造函数

3.初始化实例变量SubClass,对应App中调用SubClass的构造函数

4.此时要先加载SubClass类,同时初始化静态变量并执行静态块,对应SubClass中静态块

5.这时执行SubClass中的代码打印出“1”

6.SubClass加载完成后执行构造函数,对应SubClass中构造函数

7.SubClass构造函数最开始是执行SuperClass的构造函数,对应SubClass中调用SuperClass的构造函数

8.执行SuperClass中构造函数中的代码打印出“得到字符串构造SuperClass”

9.SuperClass构造完成return到7中的代码位置,继续执行SubClass剩余的代码

10.执行SubClass中构造函数代码打印出“2”

11.执行完SubClass构造函数return到3中的代码位置,继续执行App剩余的代码

12.执行App中构造函数代码打印出“4”

13.执行完App的构造函数return到1中代码位置,继续初始化的静态变量

14.执行静态块中的方法,答应出“3”

15.进入到main入口方法,打印出“Hello”

上面的过程就是大致的执行顺序。

回答的内容可能会有点混乱,题主看不懂的地方可以问我。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值