Java类的加载及初始化

时间:2023-02-16 22:45:14

每个类的编译代码都存在于它自己的独立文件中,该文件在需要使用该程序代码时才会被加载。通常有以下三种加载情况:

(1) 访问了子类的静态变量或静态方法:仅对类的静态变量,静态块执行初始化操作,并仅初始化一次。[代码1]

     初始化的顺序:父类的静态变量,静态块 --> 子类的静态变量,静态块 (静态域仅初始化一次)

(2) 通过构造器创建了子类的第一个对象[new XX()]:不仅对类的静态变量,静态块执行初始化操作, 还会对实例变量,块执行初始化操作[代码2]

     初始化的顺序:父类的静态变量,静态块 --> 子类的静态变量,静态块 --> 父类的实例变量,块 --> 父类的构造器 --> 子类的实例变量,块 --> 子类的构造器 (静态域仅初始化一次)

(3) 反射: 使用[Class.forName()]时同(1),使用[newInstance()]时同(2)。[代码3]

 

注意事项:

(A1) 子类访问父类的静态域,子类只会初始化父类的静态变量,静态块。不会初始化自己的。

(A2) 仅仅初始化一个数组对象是不会对此对象初始化的。

 

[代码1]

1     public static void main(String[] args) throws Exception {
2 ParentClass.parentStaticMethod();
3 }

output:

Call: ParentClass >> parentField2
Call: ParentClass >> static block
Call: ParentClass >> parentStaticMethod

 

[代码2]

1     public static void main(String[] args) throws Exception {
2 new ChildClass();
3 }

output:

Call: ParentClass >> parentField2
Call: ParentClass >> static block
Call: ChildClass >> childField2
Call: ChildClass >> static block
Call: ParentClass >> parentField1
Call: ParentClass >> block
Call: ParentClass >> constructor
Call: ChildClass >> childField1
Call: ChildClass >> block
Call: ChildClass >> constructor

 

[代码3]

1     public static void main(String[] args) throws Exception {
2 System.out.println("--execute: forName----");
3 Class<?> clazz = Class.forName("ChildClass");
4 System.out.println("--execute: newInstance----");
5 clazz.newInstance();
6 }

output:

--execute: forName----
Call: ParentClass >> parentField2
Call: ParentClass >> static block
Call: ChildClass >> childField2
Call: ChildClass >> static block
--execute: newInstance----
Call: ParentClass >> parentField1
Call: ParentClass >> block
Call: ParentClass >> constructor
Call: ChildClass >> childField1
Call: ChildClass >> block
Call: ChildClass >> constructor

 

ParentClass.java

 1 public class ParentClass {
2
3 String parentField1 = parentMethod1();
4
5 static String parentField2 = parentMethod2();
6
7 {
8 System.out.println("Call: ParentClass >> block");
9 }
10
11 static {
12 System.out.println("Call: ParentClass >> static block");
13 }
14
15 ParentClass() {
16 System.out.println("Call: ParentClass >> constructor");
17 }
18
19 String parentMethod1() {
20 System.out.println("Call: ParentClass >> parentField1");
21 return null;
22 }
23
24 static String parentMethod2() {
25 System.out.println("Call: ParentClass >> parentField2");
26 return null;
27 }
28
29 static String parentStaticMethod() {
30 System.out.println("Call: ParentClass >> parentStaticMethod");
31 return null;
32 }
33 }

 

ChildClass.java

 1 public class ChildClass extends ParentClass {
2
3 String childField1 = childMethod1();
4
5 static String childField2 = childMethod2();
6
7 {
8 System.out.println("Call: ChildClass >> block");
9 }
10
11 static {
12 System.out.println("Call: ChildClass >> static block");
13 }
14
15 ChildClass() {
16 System.out.println("Call: ChildClass >> constructor");
17 }
18
19 String childMethod1() {
20 System.out.println("Call: ChildClass >> childField1");
21 return "";
22 }
23
24 static String childMethod2() {
25 System.out.println("Call: ChildClass >> childField2");
26 return "";
27 }
28
29 static String childStaticMethod() {
30 System.out.println("Call: ChildClass >> childStaticMethod");
31 return null;
32 }
33 }