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

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

父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1 无继承情况下的Java初始化顺序: 输出结果为: 由此可以得出结论: a静态成员变量首先初始化(注意,Stat...
    姜殷俊阅读 361评论 0 1
  • Java初始化顺序:①类变量、类方法>②(父类代码)>③实例变量>④构造器当一个类要实例化时,static变量和方...
    s0me0ne阅读 191评论 0 1
  • 存在继承关系时 父类static块和静态成员变量,按顺序初始化 子类static块和静态成员变量,按顺序初始化 父...
    明明找灵气阅读 146评论 0 0
  • 前言 YY:Kitty,我最近在看Thinking in Java 这本书Kitty:喔?是么,你不是一直觉得那本...
    LilacZiyun阅读 5,560评论 12 51
  • 父类 static 块 1 执行 父类 静态成员staticSam1初始化 父类 静态成员staticSam2初始...
    YCix阅读 1,353评论 0 0