版权声明: https://blog.csdn.net/Dongguabai/article/details/85052549
package test.demo2.classloader;
/**
* @author Dongguabai
* @date 2018/12/17 17:14
*/
public class Demo {
public static int x = 0;
public static int y;
public static Demo instance = new Demo();
public Demo() {
x++;
y++;
}
public static Demo getInstance(){
return instance;
}
public static void main(String[] args) {
Demo demo = getInstance();
System.out.println(demo.x);
System.out.println(demo.y);
}
}
运行结果:
1
1
将这一段代码换一个位置:
public static Demo instance = new Demo();
运行结果:
0
1
也就是说基本一致的代码,因为一个 static 变量的顺序不同而造成了不同的结果。
Java 类加载的三个阶段:
加载:查找并且加载类的二进制数据
链接:
验证:确保被加载类的正确性
准备:为类的静态变量分配内存,并将其初始化为默认值
解析:把类中的符号引用转换为直接引用
初始化:为类的静态变量赋予正确的初始值
那么在第一个顺序的 Demo 中,“加载”、“验证”结束后进入到了“准备”阶段:
“解析”过后进行“初始化”,为类的静态变量赋予正确的初始值。此时 x=0、y=0 赋值完成了,接下来 instance 赋值,需要 new Demo() 调用 Demo 的无参构造,执行 x++,y++。所以最终输出结果是 1 和 1。
但是在更改了顺序之后:
在准备阶段:
instance = null;
x = 0;
y = 0;
在初始化阶段:
instance = new Demo(); -> x++;y++ -> x = 1; y = 1; ->x = 0;
所以在修改后输出的结果为 0 和 1。