public class A {
public static String HOST;
static {
HOST = ...;
}
}
public class B {
public static String URL;
static{
URL = A.HOST + ...;
}
}
我的问题是,如果A.HOST在B使用之前会被正确初始化吗? 这种行为是否在规范中定义?
答案 0 :(得分:8)
是的,行为定义明确here。
简而言之,引用该链接
类或接口的初始化包括执行类或接口初始化方法
<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
操作码,请求{{ 1}}。因此,将触发A.HOST
的初始化,并初始化A
。所以你会读到正确的值。
答案 1 :(得分:0)
当
class is accessed
创建实例或访问静态方法时,会执行类的静态块 或领域。
这取决于我们正在执行的代码。
在您的情况下,当我们执行A.HOST
时,它也会调用class A
的静态块。
参考this
答案 2 :(得分:0)
类的静态初始化程序在类首次运行时运行 访问,创建实例或访问静态方法 或领域。