java 静态初始化何时发生?

57hvy0tb  于 2023-01-29  发布在  Java
关注(0)|答案(3)|浏览(144)

静态字段什么时候初始化?如果我从来没有示例化一个类,但是我访问了一个静态字段,那么所有的静态块和用于示例化私有静态字段的私有静态方法是否都在那个时刻被调用(按顺序)?
如果我调用一个静态方法呢?它也运行所有的静态块吗?在调用方法之前?

mccptt67

mccptt671#

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

  • 创建类的示例,
  • 调用该类的静态方法,
  • 分配该类的静态字段,
  • 使用非恒定静态场,或
  • 对于顶级类,执行词法上嵌套在类中的assert语句1。

参见JLS 12.4.1。
还可以使用Class.forName(fqn, true, classLoader)或缩写形式Class.forName(fqn)强制类初始化(如果类尚未初始化
静态类初始化发生在什么时候?
见上文。
静态字段何时初始化?
作为静态类初始化的一部分;参见上文。
如果我从来没有示例化一个类,但是我访问了一个静态字段,那么所有的静态块和用于示例化私有静态字段的私有静态方法都在那个时刻被调用了吗?
是的。(模,没有什么是真正瞬时的。)
如果我调用一个静态方法呢?它也运行所有的静态块吗?在调用方法之前?
是的,是的。
注意,可以构造代码,在其中观察静态字段的 * default initialized * 值。
1-最后一个要点出现在Java 6到Java 8的JLS中,但显然是规范中的一个错误,最终在Java 9 JLS中得到了纠正:参见source

n9vozmp4

n9vozmp42#

静态字段在类加载(加载、链接和初始化)的初始化“阶段”初始化,包括静态初始化器和静态字段的初始化。静态初始化器按照类中定义的文本顺序执行。
请看下面的例子:

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未初始化。

omvjsjqw

omvjsjqw3#

是的,所有的静态初始化器都在你第一次访问类之前运行。如果是其他的方式,我会称之为bug。

相关问题