关于JVM加载具有静态块和非静态块的类



下面的代码,为什么打印结果是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也只初始化一次(,就像我按顺序说的那样。它看起来像这样:

  1. 新测试((
  2. 检测到测试未初始化
  3. 按顺序初始化静态变量
  4. 先拾取:public static Test test = new Test();
  5. 初始化测试后,它将触发初始化块(println("A"((。它不会触发static {},因为它已经处于处理静态的状态
  6. 一旦创建并分配了测试,它就可以拾取下一个块
  7. 处理static {}
JVM首先加载Test类以运行主方法。加载时,它为测试变量分配内存和默认值(null(。

加载后,初始化程序将以自上而下的方式运行。

首先,运行test = new Test(),它调用包含实例块(System.out.println("A")(代码的Test类的默认构造函数。因此,我们得到A作为输出。

然后,执行打印B.的静态块

之后,主方法启动,再次调用Test的默认构造函数,该构造函数打印A.

因此,输出ABA。

最新更新