Class variables (static variables) > Static blocks > Constructors > Ordinary member variables > Subclasses except static. All static modifications in JAVA will allocate space at compile time, and objects will only be allocated when used, that is, when new is used, when a subclass inherits a parent class, it obviously needs to be allocated to the parent class first. How can a son come from without a father, right?
The subject can help understand the initialization process by decompiling the compiled class file.
Instructions in the command linejavap -l -c -p -v App,执行后就会得到反编译后的内容,下面结合题主给的源码简单分析一下: 下面展示和初始化有关的部分反编译内容 Appclass file
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 "<init>":()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."<init>":()V **调用Object的构造函数**
4: aload_0
5: new #32 // class com/real/test/SubClass
8: dup
9: invokespecial #34 // Method com/real/test/SubClass."<init>":()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;
SubClassclass file
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."<init>":()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;
SuperClassclass file
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."<init>":()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;
Explain the content roughly (if the subject is interested in JVM instruction set, you can read the JVM specification, which has a very detailed explanation). The asterisked part in the decompiled content above is the annotation I added. According to the execution order of the code: 1. JVM loads the App class. The static variables in App will be initialized at this time, corresponding to the calling App in the App. Bytecode of constructor 2. Jump to the constructor of App, first initialize the parent class Object, and call Object corresponding to in App Constructor of 3. Initialize the instance variable 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, which corresponds to calling the constructor of SubClass in the App 4. At this time, the
class must be loaded first, and the static variables must be initialized at the same time. Execute the static block, corresponding to static block in SubClass. 5. At this time, executing the code in
prints out "1" 6. After
is loaded, execute the constructor, corresponding to Constructor 7. The
constructor is initially the constructor that executes
, corresponding to the constructor that calls SuperClass in SubClass 8. Execute the constructor in 🎜 The code in prints out "get string construction SuperClass" 9.🎜The construction is completedreturn to the code position in 7, and continue to execute the remaining code 10. Execute the construction in 🎜 The function code prints out "2" 11. After executing the constructor return to the code position in 3, continue executing the remaining code of App 12. Execute the constructor code in App to print out "4" 13. After executing the constructor of App, return to the code position in 1, Continue to initialize the static variables 14. Execute the method in the static block and print out "3" 15. Enter the main entry method and print out "Hello"🎜
🎜The above process is the rough execution sequence. 🎜
🎜The content of the answer may be a bit confusing. If you don’t understand something, you can ask me. 🎜
Class variables (static variables) > Static blocks > Constructors > Ordinary member variables > Subclasses except static. All static modifications in JAVA will allocate space at compile time, and objects will only be allocated when used, that is, when new is used, when a subclass inherits a parent class, it obviously needs to be allocated to the parent class first. How can a son come from without a father, right?
The subject can help understand the initialization process by decompiling the compiled
class
file.Instructions in the command line
javap -l -c -p -v App
,执行后就会得到反编译后的内容,下面结合题主给的源码简单分析一下:下面展示和初始化有关的部分反编译内容
App
class fileSubClass
class fileSuperClass
class fileExplain the content roughly (if the subject is interested in
class must be loaded first, and the static variables must be initialized at the same time. Execute the static block, corresponding toJVM instruction set
, you can read theJVM
specification, which has a very detailed explanation).The asterisked part in the decompiled content above is the annotation I added. According to the execution order of the code:
1. JVM loads the
App
class. The static variables inApp
will be initialized at this time, corresponding to thecalling App in the App. Bytecode of constructor
2. Jump to the constructor of
App
, first initialize the parent classObject
, and call Object corresponding toin App Constructor of
3. Initialize the instance variable
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
, which corresponds tocalling the constructor of SubClass in the App
4. At this time, the
static block
in SubClass. 5. At this time, executing the code in
prints out "1"
is loaded, execute the constructor, corresponding to Constructor6. After
7. The
constructor is initially the constructor that executes
, corresponding to theconstructor that calls SuperClass in SubClass
8. Execute the constructor in 🎜 The code in prints out "get string construction SuperClass"
9.🎜The construction is completed
return
to the code position in 7, and continue to execute the remaining code10. Execute the construction in 🎜 The function code prints out "2"
11. After executing the constructor
return
to the code position in 3, continue executing the remaining code ofApp
12. Execute the constructor code in
App
to print out "4"13. After executing the constructor of
App
,return
to the code position in 1, Continue to initialize the static variables14. Execute the method in the static block and print out "3"
15. Enter the
main
entry method and print out "Hello"🎜 🎜The above process is the rough execution sequence. 🎜 🎜The content of the answer may be a bit confusing. If you don’t understand something, you can ask me. 🎜