关于JVM加载类与静态块和非静态块[重复]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于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只会为每个类初始化一次静态(如果我没有弄错的话,每个ClassLoader),就像我按顺序说的那样。它看起来像这样:

  1. 新测试()
  2. 检测到Test未初始化
  3. 按顺序初始化静态变量
  4. 先拿起来:public static Test test = new Test();
  5. 在启动测试后,它将触发初始化块(println(“A”))。它不会触发qazxsw poi,因为它已经处于处理静态的状态
  6. 一旦创建并分配了测试,它就可以获取下一个块
  7. 处理static {}
另一答案

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

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

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

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

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

因此,输出ABA。

以上是关于关于JVM加载类与静态块和非静态块[重复]的主要内容,如果未能解决你的问题,请参考以下文章

java中成员变量代码块构造函数运行顺序

静态代码块和单例混合

两个案例,解读静态代码块和构造代码块

JVM活学活用——类加载机制

Java的静态块和初始化块分别何时执行?有啥区别?

关于静态变量和非静态变量的区别