静态类初始化什么时候发生?

新手上路,请多包涵

什么时候初始化静态字段?如果我从不实例化一个类,但我访问了一个静态字段,那么所有用于实例化私有静态字段的静态块和私有静态方法是否在那一刻被调用(按顺序)?

如果我调用静态方法怎么办?它是否也运行所有静态块?方法之前?

原文由 Tony R 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 678
2 个回答

类的静态初始化通常发生在以下事件之一第一次发生之前:

  • 创建该类的一个实例,
  • 调用类的静态方法,
  • 分配了类的静态字段,
  • 使用非常量静态字段,或
  • 对于顶级类,执行词法嵌套在类中的 assert 语句1 。

请参阅 JLS 12.4.1

也可以通过使用 Class.forName(fqn, true, classLoader) 或缩写形式 Class.forName(fqn) 强制类初始化(如果它尚未初始化)


静态类初始化什么时候发生?

看上面。

什么时候初始化静态字段?

作为静态类初始化的一部分;看上面。

如果我从不实例化一个类,但我访问了一个静态字段,那么所有用于实例化私有静态字段的静态块和私有静态方法是否在那一刻被调用(按顺序)?

是的。 (模数没有什么是真正瞬时的。)

如果我调用静态方法怎么办?它是否也运行所有静态块?方法之前?

是的,是的。


请注意,可以构造代码,您可以在其中观察静态字段的 默认初始化 值。


1 - 最后的要点出现在 Java 6 到 Java 8 的 JLS 中,但这显然是规范中的一个错误。它最终在 Java 9 JLS 中得到纠正:请参阅 source

原文由 Stephen C 发布,翻译遵循 CC BY-SA 4.0 许可协议

静态字段在类加载(加载、链接和初始化)的 初始化“阶段”期间被初始化,其中包括静态初始化器和其静态字段的初始化。静态初始化程序按照类中定义的文本顺序执行。

考虑这个例子:

 public class Test {

   static String sayHello()  {
      return a;
   }

   static String b = sayHello(); // a static method is called to assign value to b.
                                 // but its a has not been initialized yet.

   static String a = "hello";

   static String c = sayHello(); // assignes "hello" to variable c

    public static void main(String[] arg) throws Throwable {
         System.out.println(Test.b); // prints null
         System.out.println(Test.sayHello()); // prints "hello"
    }
}

Test.b 打印 null 因为当在静态范围内调用 sayHello 时,静态变量 a 未初始化。

原文由 naikus 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题