Java中的初始化顺序,静态块内的构造函数

时间:2019-03-02 15:35:45

标签: java constructor static initialization

考虑到标准的Java初始化顺序规则,我不清楚为什么下面的代码

public class Foo {

    static { new Foo(); }

    static{ System.out.println("static code"); }

    { System.out.println("non static code"); }

    public Foo() { System.out.println("constructor"); }

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

输出以下内容:

non static code
constructor
static code

3 个答案:

答案 0 :(得分:1)

因此,静态加载块将在类加载器加载类后立即执行。因此,您的第一个静态块static { new Foo(); }首先执行,这进一步调用了构造函数new Foo();。按照Java docs非静态块将由编译器复制到每个构造函数,这意味着System.out.println("non static code");将被复制到构造函数public Foo() { System.out.println("constructor"); }。因此,它将先打印non static code,然后再打印constructor。在执行完第一个静态块之后,它将执行第二个静态块,并输出最后一个static code

编译后,您的代码类似于以下代码:

public class Foo {

    static { new Foo(); }

    static{ System.out.println("static code"); }

    public Foo() { 
       System.out.println("non static code");
       System.out.println("constructor"); 
    }

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

答案 1 :(得分:1)

JLS表示

  • 初始化类时,将按程序源代码顺序执行静态块和静态变量初始化。

  • 实例初始化时,将按程序源代码顺序执行实例块和实例变量初始化。在超级实例初始化之后之后和在构造函数主体执行之前 发生这种情况。

在您的示例中,第一个静态对象创建Foo的实例。这导致Foo的实例块在执行第一个静态块的同时 被执行。因此,顺序为:

  1. 该类已加载
  2. Foo的静态初始化已触发
  3. 执行第一个静态块,该块执行new Foo()
    1. 执行实例块-打印“非静态代码”
    2. 执行构造函数-打印“构造函数”
  4. 第一个静态块结束。
  5. 第二个静态块被执行-打印“静态代码”。
  6. 主要方法被调用。

答案 2 :(得分:0)

要重构代码,请执行以下步骤:

1)删除非静态初始化块-编译器在实际构造函数中的代码之前放置

public class Foo {

    static { new Foo(); }

    static{ System.out.println("static code"); }

    public Foo() {
        System.out.println("non static code");
        System.out.println("constructor");
     }

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

2)加入静态初始化块-参见here

  

一个类可以具有任意数量的静态初始化块,并且它们   可以出现在班级正文中的任何位置。运行系统保证   静态初始化块的顺序是:   出现在源代码中。

public class Foo {

    static {
        new Foo();
        System.out.println("static code");
     }

    public Foo() {
        System.out.println("non static code");
        System.out.println("constructor");
     }

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

3)从那里应该很明显。