首先观察下面代码,并想下输出结果是什么
public class SinglePattern{
private static SinglePattern instance = new SinglePattern();//在类的装载就直接实例化
public static int a;
public static int b = 2;
private SinglePattern(){
a++;
b++;
}
public static SinglePattern getInstance() {
return instance;
}
public static void main(String[] args) {
SinglePattern ins = SinglePattern.getInstance();
System.out.println("a:="+ins.a);
System.out.println("b:="+ins.b);
}
}
上面就是一个单例模式呗
然后我不做任何修改,改变类实例化的一行代码的位置,想想输出结果是什么?
public class SinglePattern{
public static int a;
public static int b = 2;
private static SinglePattern instance = new SinglePattern();//在类的装载就直接实例化
private SinglePattern(){
a++;
b++;
}
public static SinglePattern getInstance() {
return instance;
}
public static void main(String[] args) {
SinglePattern ins = SinglePattern.getInstance();
System.out.println("a:="+ins.a);
System.out.println("b:="+ins.b);
}
}
想到结果了没??
第一个运行结果为:
第二个运行结果为:
WTF?
就改变一行代码的位置,没有其它大的改动,就结果不一样了!!
其实这是类加载过程产生的问题,对类加载过程详细了解。可以参考:https://blog.csdn.net/weijifeng_/article/details/79894742
对于两个代码分析详解
1 .准备阶段
instance = null;
a = 0;
b = 0;
2 .初始化阶段
new SinglePattern() ; a = 1; b = 1;
public static int a; a没有指定值,就是上一步的1
public static int b = 2; b有指定初始值,初始化阶段时,b = 2;
所以这就是第一种执行结果为a = 1, b = 2的原因了
1 .准备阶段
instance = null;
a = 0;
b = 0;
2 .初始化阶段
public static int a; a没有指定值,就是上一步的0
public static int b = 2; b有指定初始值,初始化阶段时,b = 2;
new SinglePattern() ; a = 1; b = 3;
这就是产生结果不一样的原因了!
类加载的准备阶段和初始化阶段都严格执行自己的工作,并且在初始化阶段,严格按照指令从上到下的顺序就行内存值分配
所以在了解装载的过程,就应该清楚自己取什么阶段的值,保证取值不会发生错误