Java 种中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序

Java 类中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序Java 类中类属性 (static 变量)

Java 类中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序



Java 类中类属性 (static 变量) 和对象属性 (非 static 变量) 的初始化顺序可以用如下程序测试:

/**

* @(#) Test.java
* @author fancy
*/

public class Test {

static String a = "string-a";
static String b;

String c = "stirng-c";
String d;

static {
printStatic("before static");
b = "string-b";
printStatic("after static");
}

public static void printStatic(String title) {
System.out.println("---------" + title + "---------");
System.out.println("a = "" + a + """);
System.out.println("b = "" + b + """);
}

public Test() {
print("before constructor");
d = "string-d";
print("after constructor");
}

public void print(String title) {
System.out.println("---------" + title + "---------");
System.out.println("a = "" + a + """);
System.out.println("b = "" + b + """);
System.out.println("c = "" + c + """);
System.out.println("d = "" + d + """);
}

public static void main(String[] args) {
new Test();
}

}

首先,我把 main() 方法注释掉,运行结果如下:

---------before static---------
a = "string-a"
b = "null"
---------after static---------
a = "string-a"
b = "string-b"
java.lang.NoSuchMethodError: main
Exception in thread "main"
Process completed.

然后,取消对 main() 方法的注释,运行结果如下:

---------before static---------
a = "string-a"
b = "null"
---------after static---------
a = "string-a"
b = "string-b"
---------before constructor---------
a = "string-a"
b = "string-b"
c = "stirng-c"
d = "null"
---------after constructor---------
a = "string-a"
b = "string-b"
c = "stirng-c"
d = "string-d"

由此可以看出 Java 类属性和对象属性的初始化顺序如下:

① 类属性 (静态变量) 定义时的初始化,如上例的 static String a = "string-a";
② static 块中的初始化代码,如上例 static {} 中的 b = "string-b";
③ 对象属性 (非静态变量) 定义时的初始化,如上例的 String c = "stirng-c";
④ 构造方法 (函数) 中的初始化代码,如上例构造方法中的 d = "string-d";

在此过程中 ② 和 ③ 的顺序无所确定,因为在静态块中无法打印出非静态变量。同样是因为这个原因,知道他们的顺序对我们写程序也毫无帮助。再因为类成员 (静态成员) 是在第一次使用到类的时候就进行了相应的初始化,而对象成员 (非静态成员) 则需要生成类实例 (即对象) 时才能初始化,所以我把 ③ 排在了 ② 的后面。再申明一次,它们究竟谁先谁后,从代码上是不能确定的,恐怕需要去研究一下 JVM (Java 虚拟机) 的执行过程才行。