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

时间:2015-07-15 10:55:00

标签: java language-lawyer

public class A {
  public static String HOST;

  static {
    HOST = ...;
  }
}

public class B {
    public static String URL;

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

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

3 个答案:

答案 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)

  

类的静态初始化程序在类首次运行时运行   访问,创建实例或访问静态方法   或领域。

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