什么时候进行静态类初始化?

时间:2010-08-17 03:56:25

标签: java static initialization

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

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

3 个答案:

答案 0 :(得分:150)

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

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

JLS 12.4.1

也可以使用Class.forName(fqn, true, classLoader)或短格式Class.forName(fqn)

强制类初始化(如果尚未初始化)

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

答案 1 :(得分:13)

静态字段在类加载(加载,链接和初始化)的initialization“阶段”初始化,包括静态初始化器和静态字段的初始化。静态初始值设定项按类中定义的文本顺序执行。

考虑一下这个例子:

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

答案 2 :(得分:1)

是的,所有静态初始值设定项都是在您第一次访问类之前运行的。如果是其他任何方式,我会称之为错误。