Java静态块指的是另一个类中的静态变量

byd*_*sky 8 java language-lawyer

public class A {
  public static String HOST;

  static {
    HOST = ...;
  }
}

public class B {
    public static String URL;

    static{
         URL = A.HOST + ...;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果A.HOST在B使用它之前会被正确初始化吗?这种行为是否在规范中定义?

xp5*_*500 8

是的,行为在这里定义得很好.

简而言之,引用该链接

类或接口的初始化包括执行类或接口初始化方法 <clinit>

...

只有以下结果才能初始化类或接口:

执行引用类或接口的任何一个Java虚拟机指令new,getstatic,putstatic或invokestatic(§new,§getstatic,§putstatic,§invokestatic).所有这些指令都通过字段引用或方法引用直接或间接引用类.

在执行新指令时,如果尚未初始化引用的类或接口,则对其进行初始化.

执行getstatic,putstatic或invokestatic指令后,如果尚未初始化,则声明已解析的字段或方法的类或接口已初始化.

第一次调用java.lang.invoke.MethodHandle实例,该实例是Java虚拟机(第5.4.3.5节)解析方法句柄并且具有2种类型(REF_getStatic),4(REF_putStatic)的结果,或6(REF_invokeStatic).

在类库(第2.12节)中调用某些反射方法,例如,在类Class或包java.lang.reflect中.

其子类之一的初始化.

它被指定为Java虚拟机启动时的初始类(第5.2节).

<clinit>方法是由编译器创建的方法,用于初始化静态变量并具有放在static块中的代码

在你的情况下,当static类的块B运行时(这<clinit>将是什么),它将有一个getStatic操作码,请求A.HOST.因此初始化A将被触发并A.HOST初始化.所以你会读到正确的值.