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

时间:2018-07-24 08:37:38

标签: java 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();
    }    

}

2 个答案:

答案 0 :(得分:0)

这是因为静电是按顺序处理的。当您将其更改为:

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只会对每个类(如果我没记错的话,对每个ClassLoader)都初始化一次静态,就像我按顺序说的那样。看起来像这样:

  1. 新的Test()
  2. 检测到测试未初始化
  3. 按顺序初始化静态vars
  4. 先接送:public static Test test = new Test();
  5. 启动Test之后,它将触发初始化块(println(“ A”))。它不会触发static {},因为它已经处于处理静态的状态
  6. 创建并分配测试后,便可以提取下一个程序段
  7. 处理static {}

答案 1 :(得分:0)

JVM首先加载Test类以运行main方法。加载时,它将为测试变量分配内存和默认值(空)。

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

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

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

此后,main方法开始,再次调用Test的默认构造函数,该函数将打印A。

因此,输出ABA。