你好stackoverflow成员, 这是一个与“类加载时间”的实际含义相关的小问题。
例如以下代码:
public class Sequence {
Sequence() {
System.out.print("c ");
}
{
System.out.print("y ");
}
public static void main(String[] args) {
System.out.println("Indeed");
new Sequence().go();
}
void go() {
System.out.print("g ");
}
static { System.out.println("x "); }
}
它首先打印出静态的“x”,因此静态init块总是在“类加载时”加载。 我明白了,但你确切知道这个加载时间到了吗?我认为当第一个类通过创建第一个对象在main方法中被调用时,但是在这种情况下,结果应该通过首先打印出“Indeed”而不同。 任何人都可以帮我澄清这个疑问吗?我已经检查了其他帖子一般性地谈论这个论点,但我认为会更清楚(至少对我来说)在确切的时候,在上面报告的代码中,“类加载时间”发生。
提前致谢。
答案 0 :(得分:3)
由于您的main
方法位于类Sequence
中的,因此需要首先由JVM加载。因此,"x"
是第一个要打印出来的东西是完全合理的。
答案 1 :(得分:3)
你是对的,加载类时静态块为run
。当你运行程序时,就会发生这种情况。因为main方法本身位于类Sequence
内,所以x
之前的输出Indeed
是正确的。
答案 2 :(得分:3)
您的问题的答案位于JLS Chapter 12.4.1 When Initialization Occurs
类或接口类型
T
将在紧接之前初始化 首次出现以下任何一种情况:
T
是一个类,并创建了T
的实例。T
是一个类,调用T
声明的静态方法。- 分配了
T
声明的静态字段。- 使用
T
声明的静态字段,该字段不是常量变量(§4.12.4)。T
是顶级类(第7.6节),并且执行在T
(第8.1.3节)内词法嵌套的断言语句(第14.10节)。
我建议你在JLS Chapter 12.4. Initialization of Classes and Interfaces
上面开始阅读几行从Chapter 12. Execution开始,它确切地描述了何时 需要加载一个类。初始化将在加载后完成。
答案 3 :(得分:2)
静态init块在类加载时执行并不是真的。它们在类初始化时间执行。前者发生的确切时间点是未指定的,而后者则有严格的规范:它在类的第一次运行时访问时发生。
答案 4 :(得分:1)
在JVM调用Sequence
方法之前必须加载类main
,这会导致静态初始化,因此x
首先要成为{{1}}打印出来。