Java初始化顺序

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

所以我们可以总结出如下顺序:

父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器

你可能感兴趣的:(Java初始化顺序)