Java 静态块引用另一个中的静态变量 class

Java static block refer to static variable in another class

public class A {
  public static String HOST;

  static {
    HOST = ...;
  }
}

public class B {
    public static String URL;

    static{
         URL = A.HOST + ...;
    }
}

我的问题是 A.HOST 是否会在 B 使用之前正确初始化? 此行为是否在规范中定义?

The static block for a class gets executed when the class is accessed, either to create an instance, or to access a static method or field.

这取决于我们正在执行的代码。

在您的情况下,当我们执行 A.HOST 时,它也会调用 class A 的静态块。

参考this

The static initializer for a class gets run when the class is first accessed, either to create an instance, or to access a static method or field.

来源:In what order do static initializer blocks in Java run?

是的,行为定义明确 here

简而言之,引用自link

Initialization of a class or interface consists of executing the class or interface initialization method <clinit>

...

A class or interface may be initialized only as a result of:

The execution of any one of the Java Virtual Machine instructions new, getstatic, putstatic, or invokestatic that references the class or interface (§new, §getstatic, §putstatic, §invokestatic). All of these instructions reference a class directly or indirectly through either a field reference or a method reference.

Upon execution of a new instruction, the referenced class or interface is initialized if it has not been initialized already.

Upon execution of a getstatic, putstatic, or invokestatic instruction, the class or interface that declared the resolved field or method is initialized if it has not been initialized already.

The first invocation of a java.lang.invoke.MethodHandle instance which was the result of resolution of a method handle by the Java Virtual Machine (§5.4.3.5) and which has a kind of 2 (REF_getStatic), 4 (REF_putStatic), or 6 (REF_invokeStatic).

Invocation of certain reflective methods in the class library (§2.12), for example, in class Class or in package java.lang.reflect.

The initialization of one of its subclasses.

Its designation as the initial class at Java Virtual Machine start-up (§5.2).

<clinit> 方法是初始化静态变量的方法(由编译器创建)并具有您放入 static 块中的代码

在你的例子中,当 class Bstatic 块运行时(这是 <clinit> 会做的),它将有一个 getStatic 操作码,请求 A.HOST。所以会触发A的初始化,A.HOST的初始化。所以你会读到正确的值。

在 main() 方法执行之前,将执行一个静态块。