Java 静态类初始化何时发生?
静态字段何时初始化?如果我从未实例化过一个类,但我访问了一个静态字段,那么用于实例化私有静态字段的所有静态块和私有静态方法都是按顺序调用的吗Java 静态类初始化何时发生?,java,static,initialization,Java,Static,Initialization,静态字段何时初始化?如果我从未实例化过一个类,但我访问了一个静态字段,那么用于实例化私有静态字段的所有静态块和私有静态方法都是按顺序调用的吗 如果我调用一个静态方法呢?它是否也运行所有静态块?在使用该方法之前?是的,在您首次访问类之前,所有静态初始值设定项都会运行。如果是其他方式,我会称之为bug。静态字段在类加载、链接和初始化阶段初始化,包括静态初始值设定项及其静态字段的初始化。静态初始值设定项按照类中定义的文本顺序执行 举个例子: public class Test { static
如果我调用一个静态方法呢?它是否也运行所有静态块?在使用该方法之前?是的,在您首次访问类之前,所有静态初始值设定项都会运行。如果是其他方式,我会称之为bug。静态字段在类加载、链接和初始化阶段初始化,包括静态初始值设定项及其静态字段的初始化。静态初始值设定项按照类中定义的文本顺序执行 举个例子:
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未初始化。类的静态初始化通常在第一次发生以下事件之前立即发生: 创建该类的一个实例, 调用该类的静态方法, 指定了类的静态字段, 使用非恒定静态场,或 对于顶级类,将执行嵌套在该类中的assert语句1。 看 如果类尚未使用或缩写形式初始化,也可以强制类初始化
1-最后一个要点出现在Java 6到Java 8的JLS中,但这显然是规范中的一个错误。它最终在Java 9 JLS中得到了纠正:请参阅。严格来说,初始化不是类加载的一个阶段。事实上,如果应用程序没有实际使用某些类,它们可能会被加载,但永远不会被初始化。@Stephen C你是对的,我使用它是因为没有更好的术语,也许我会引用它。@StephenC这是否意味着当类加载发生时,它将内存分配给静态变量和方法,但是这些静态变量没有用代码中提供的值初始化?因为在这里,当b->sayHello->a,“a”在内存中,但它的值还没有被分配。基本上,是的。但是有一个常见的陷阱。原语和字符串被替换,不被引用。如果从某个类MyClass{private int=Other.VAL;}引用另一个类{public static final int VAL=10;},则不会加载另一个类。相反,编译器将在编译时简单地替换最后一个字段。@RafaelWinterhalter-yes。。。这是常量静态字段的情况。@RafaelWinterhalter,并非所有“静态最终”原语或字符串变量都是如此,只有那些由常量表达式初始化的变量才是如此。是的,当这是常见情况时,字段甚至不需要是静态的。这是同一种编程语言。是的。与静态初始值设定项块类似:有一些方法可以在不初始化类的情况下引用类。