Java的static修饰变量,方法,代码块的初始化顺序
测试代码
package test;
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 Test() {
print("before constructor");
d = "string-d";
print("after constructor");
}
public static void main(String[] args) {
new Test();
}
public static void printStatic(String title) {
System.out.println("---------" + title + "---------");
System.out.println("a = \"" + a + "\"");
System.out.println("b = \"" + b + "\"");
}
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 + "\"");
}
}
运行结果
---------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"
分析结果
- static函数在constructor函数之前。 这是因为static修饰的变量和代码块在JVM加载该类的时候就执行了,而constructor是在实例化的时候才执行。
- 修改测试代码,将static修饰的变量放到static修饰代码块之后,发现before static的结果都为null,说明static修饰的代码块和变量初始化顺序是谁写在前面谁先初始化。
- 无法分析类的非静态变量和静态变量谁先初始化,需要研究JVM的实现。
总结
Java 类属性和对象属性的初始化顺序
1. static修饰的变量和代码块,两者的先后取决于谁写在前面
2. 对象的非静态变量
3. 构造函数的初始化代码