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"
}
}
3条答案
按热度按时间mccptt671#
类的静态初始化通常在以下事件之一第一次发生之前立即进行:
参见JLS 12.4.1。
还可以使用
Class.forName(fqn, true, classLoader)
或缩写形式Class.forName(fqn)
强制类初始化(如果类尚未初始化静态类初始化发生在什么时候?
见上文。
静态字段何时初始化?
作为静态类初始化的一部分;参见上文。
如果我从来没有示例化一个类,但是我访问了一个静态字段,那么所有的静态块和用于示例化私有静态字段的私有静态方法都在那个时刻被调用了吗?
是的。(模,没有什么是真正瞬时的。)
如果我调用一个静态方法呢?它也运行所有的静态块吗?在调用方法之前?
是的,是的。
注意,可以构造代码,在其中观察静态字段的 * default initialized * 值。
1-最后一个要点出现在Java 6到Java 8的JLS中,但显然是规范中的一个错误,最终在Java 9 JLS中得到了纠正:参见source。
n9vozmp42#
静态字段在类加载(加载、链接和初始化)的初始化“阶段”初始化,包括静态初始化器和静态字段的初始化。静态初始化器按照类中定义的文本顺序执行。
请看下面的例子:
Test.B打印
null
,因为在静态范围内调用sayHello
时,静态变量a
未初始化。omvjsjqw3#
是的,所有的静态初始化器都在你第一次访问类之前运行。如果是其他的方式,我会称之为bug。