JVM首先加载Test类以运行主方法。加载时,它为测试变量分配内存和默认值(null(。
下面的代码,为什么打印结果是ABA。在我看来,JVM将首先加载静态块语句,然后加载其他语句,所以B将首先打印。
public class Test{
public static Test test = new Test();
{
System.out.println("A");
}
static {
System.out.println("B");
}
public static void main(String[] args) {
Test test = new Test();
}
}
这是因为静态处理是按顺序进行的。当您将其更改为:
class Test {
static {
System.out.println("B");
}
public static Test test = new Test();
{
System.out.println("A");
}
public static void main(String[] args) {
Test test = new Test();
}
}
你将获得BAA。
JVM每个类只初始化static一次(如果我没有弄错的话,每个ClassLoader也只初始化一次(,就像我按顺序说的那样。它看起来像这样:
- 新测试((
- 检测到测试未初始化
- 按顺序初始化静态变量
- 先拾取:
public static Test test = new Test();
- 初始化测试后,它将触发初始化块(println("A"((。它不会触发
static {}
,因为它已经处于处理静态的状态 - 一旦创建并分配了测试,它就可以拾取下一个块
- 处理
static {}
加载后,初始化程序将以自上而下的方式运行。
首先,运行test = new Test()
,它调用包含实例块(System.out.println("A")
(代码的Test类的默认构造函数。因此,我们得到A作为输出。
然后,执行打印B.的静态块
之后,主方法启动,再次调用Test的默认构造函数,该构造函数打印A.
因此,输出ABA。