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

问题描述 投票:-2回答:3

考虑到标准的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
java constructor static initialization
3个回答
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
投票

JLS说

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

在您的示例中,第一个静态创建Foo的实例。这会导致在执行第一个静态块时执行Foo的实例块。所以,顺序是:

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

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)从那里,它应该是显而易见的。

© www.soinside.com 2019 - 2024. All rights reserved.