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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中的初始化顺序,静态块内的构造函数相关的知识,希望对你有一定的参考价值。

考虑到标准的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
答案

因此,只要类加载器加载了类,静态块就会执行。所以,你的第一个静态块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) {}
}
另一答案

JLS说

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

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

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

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

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

以上是关于java中的初始化顺序,静态块内的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

随笔13 java中的普通代码块,构造代码块,静态代码块

java学习之静态块显示初始化块构造函数this在构造函数中的调用,区别联系与调用顺序

静态代码块构造代码块构造函数以及Java类初始化顺序

java中的静态代码块、代码块、构造器的执行顺序是怎样呢,这三者有啥作用呢

静态代码块构造代码块构造函数以及Java类初始化顺序

java 静态代码块 代码块 构造函数 静态成员变量 成员变量的初始化顺序