Java初始化的顺序如下:
[静态变量, 静态初始化块] > [变量, 变量初始化块] > 构造方法
静态变量和静态初始化块之间没有先后关系, 遵循代码的先后顺序, 写在前面就先初始化, 所以如果你想要在静态初始化块里引用在之后声明的一个静态变量, 会收到一个Compile Error
.
public class InitialOrder {
public static final void main(String[] args) {
System.out.println("test: " + Test.STATIC_VARIABLE); //flag1
//Test test = new Test(); //flag2
}
}
class Test {
static String STATIC_VARIABLE = "static_variable";
static {
System.out.println(STATIC_VARIABLE);
System.out.println("static_code_block");
}
static {
System.out.println("another_code_block");
}
private String memberVariable = "member_variable";
{
System.out.println(memberVariable);
System.out.println("code_block");
}
Test() {
System.out.println("construction method");
}
}
输出:
static_variable
static_code_block
another_code_block
test: static_variable
可以看到, 当一个类的静态变量被引用时, 所有的静态变量以及静态初始化块都将被初始化. 这时候, 由于还没有实例化对象, 故非静态的初始化都不会进行.
如果我们注释掉flag1处代码, 恢复flag2处代码, 运行结果如下:
static_variable
static_code_block
another_code_block
member_variable
code_block
construction method
当一个类实例化时, 静态和非静态的初始化都将进行. 同样, 非静态的初始化同样有要求先后顺序, 即一个变量初始化块不能引用在之后声明的一个变量, Illegal forward reference
.
带继承关系的初始化顺序
public class InitialOrderWithInherit {
public static void main(String[] args) {
Child child = new Child();
}
}
class Father {
static String STATIC_VARIABLE = "father_static_variable";
static {
System.out.println(STATIC_VARIABLE);
System.out.println("father_static_code_block");
}
private String memberVariable = "father_member_variable";
{
System.out.println(memberVariable);
System.out.println("father_code_block");
}
Father() {
System.out.println("father_construction");
}
}
class Child extends Father {
static String STATIC_VARIABLE = "child_static_variable";
static {
System.out.println(STATIC_VARIABLE);
System.out.println("child_static_code_block");
}
private String memberVariable = "child_member_variable";
{
System.out.println(memberVariable);
System.out.println("child_code_block");
}
Child() {
System.out.println("child_construction");
}
}
输出:
father_static_variable
father_static_code_block
child_static_variable
child_static_code_block
father_member_variable
father_code_block
father_construction
child_member_variable
child_code_block
child_construction
若仅仅是引用了Child.STATIC_VARIABLE
, 输出如下:
father_static_variable
father_static_code_block
child_static_variable
child_static_code_block
child_static_variable
所以我们可以总结出如下顺序:
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器