Java 编译器如何决定静态和实例成员/块的执行优先级

Ami*_*mar 2 java compiler-construction static-members

public class Test {
    public static void main(String str[]) {
        Hello h=Hello.INS1;
    }
}

class Hello {
 static Hello INS1=new Hello();
 static Hello INS2=new Hello(12);
{
    System.out.println("Instance Block");
}
static {
        System.out.println("Static Block");
}
private Hello() {
    System.out.println("Hello() Block");
}
private Hello(int ab) {
    System.out.println("Hello() Block");
}
}
Run Code Online (Sandbox Code Playgroud)

静态块总是先执行,但这段代码给出了一些我无法确定的东西。这里究竟发生了什么......?

输出:实例块 Hello() 块实例块 Hello() 块静态块

Ank*_*wat 5

类加载到JVM时执行静态块,创建对象时执行实例块。

可以有多个静态和实例初始化块,它们本身的执行顺序将按照它们从上到下出现的顺序。

例如考虑以下代码。

public class InitBlockExample{
    {
       System.out.println("X");
    }
    {
       System.out.println("Y");
    }
    static{
       System.out.println("A");
    }
    static{
       System.out.println("B");
    }
}
Run Code Online (Sandbox Code Playgroud)

创建此类的对象时(需要同时显示静态块和实例块对象创建),输出将如下所示:-

A
B
X
Y

静态语句也与静态块一起参与订单执行,首先执行的是那些先执行的,这件事适用于您的问题,您创建的类变量是静态的,因此它们将首先执行,因为它们需要构造函数执行首先执行构造函数,但在构造函数之前执行所有实例初始化块,因此首先执行它们,然后是构造函数,最后是静态块。如果你把

static Hello INS1=new Hello();
static Hello INS2=new Hello(12);
Run Code Online (Sandbox Code Playgroud)

在静态块之后然后输出将被反转并且静态块将首先被执行。