静态成员初始化时遇到得神奇问题

早上一个同学问我的问题

package com.example.eurekaclient;

/**
 * @ClassName TestStatic
 * @Description TODO
 * @Author Mr.G
 * @Date 2018/9/25 10:14
 * @Version 1.0
 */
public class TestStatic {

    private static TestStatic  A=new TestStatic();
    {
        System.out.println("A");
    }
    static {
        System.out.println("B");
    }
    public static void main(String[] args){
        TestStatic A=new TestStatic();
    }
 }

我当时没怎么思考就觉得输出结果是BAA,但是答案是ABA,于是我打了断点进去

静态成员初始化时遇到得神奇问题

发现 是初始化 static TesstStatic A 直接输出A就初始化完毕,然后执行静态代码块B,然后执行main函数,此时类已经加载完毕,需要创建新的实例A ,需要运行普通代码块A,

在网上找了点类加载的资料

静态成员初始化时遇到得神奇问题

静态成员初始化时遇到得神奇问题

通过上面的资料的理解,我的想法如下,程序得入口是main函数,所以先执行main函数里得方法,需要实例化这个类,但是是第一次需要把这个类得class文件加载到jvm里,装载,然后是把符号引用转化成直接引用,这里有个静态引用A,所以变成直接引用,需要执行普通代码块,输出A(我猜测这里,它先去虚拟机里面找,发现类已经加载了,所以不执行静态代码块,这个可能是个同步问题(个人猜测)),然后类加载好了,回到主函数,需要实例化A,此时触发初始化,执行静态代码块,输出B,然后执行普通代码块,输出A

初始化条件

静态成员初始化时遇到得神奇问题

参考资料:http://www.cnblogs.com/ivanfu/archive/2012/02/12/2347817.html