静态成员初始化时遇到得神奇问题
早上一个同学问我的问题
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