【问题标题】:Java static block refer to static variable in another classJava静态块引用另一个类中的静态变量
【发布时间】:2015-10-04 09:05:39
【问题描述】:
public class A {
  public static String HOST;

  static {
    HOST = ...;
  }
}

public class B {
    public static String URL;

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

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

【问题讨论】:

  • 只运行一个简单的测试看看它是否被初始化
  • 如果你先对 A 进行任何引用,A 将被完全初始化,并且每当你第一次调用 B 时,它都会正常工作。如果先调用B,遇到A.HOST会级联到A。
  • 有趣的是,如果 A 有类似 HOST = B.FOO 的东西。不过,不确定它是否会编译。

标签: java language-lawyer


【解决方案1】:

是的,该行为已明确定义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 块中的代码

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

【讨论】:

  • 你的结论是yes还是no,A会在B使用之前被初始化?
  • @user3360241 刚刚编辑,如果还不清楚请告诉我。
【解决方案2】:

class is accessed 创建实例或访问静态方法时,将执行类的静态块 或字段。

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

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

参考this

【讨论】:

    【解决方案3】:

    类的静态初始化程序在类第一次运行时运行 访问,要么创建实例,要么访问静态方法 或字段。

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 您能否解释一下您的答案与所提问题的关系?
      • 我的意思是静态块中的代码在main方法之前执行,B类写在A类旁边,可能是字符串被初始化了,被B类访问就没有问题了。跨度>
      • 我认为你没有理解这个问题。 B.URLA.HOST 都是静态的。但是B.URL 初始化需要A.HOST。所以问题是A在初始化时B.URL还没有初始化,会不会有什么问题?
      • 我只是对程序流程感到困惑,是的,这是一个问题。感谢您的评论。
      猜你喜欢
      • 1970-01-01
      • 2012-05-04
      • 2021-08-31
      • 1970-01-01
      • 2019-03-04
      • 2018-03-15
      • 2011-09-01
      • 2019-03-10
      • 2012-09-06
      相关资源
      最近更新 更多