public class MainTest {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1==" + obj.counter1);
System.out.println("obj.counter2==" + obj.counter2);
}
}
class Singleton {
public static int counter1;
public static int counter2 = 0;
private static Singleton obj = new Singleton();
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
}
结果为:
obj.counter1==1
obj.counter2==1
再看:
public class MainTest {
public static void main(String[] args) {
Singleton obj = Singleton.getInstance();
System.out.println("obj.counter1==" + obj.counter1);
System.out.println("obj.counter2==" + obj.counter2);
}
}
class Singleton {
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
private Singleton() {
counter1++;
counter2++;
}
public static Singleton getInstance() {
return obj;
}
}
结果为:
obj.counter1==1
obj.counter2==0
问题:为什么后者的counter2会是0而不是1?
=================================================================================
参考理解:
第一种:
在main函数里调用Singleton 的静态方法时
虚拟机只加载Singleton 类并初始化其中的静态字段,但是并不分配空间创建此类的对象。
public static int counter1;
public static int counter2 = 0;
private static Singleton obj = new Singleton();
执行了静态变量counter1,counter2初始化后,遇到new Singleton() 指令,然后虚拟机又开始检查Singleton 是否被初始化,检查得知没有完全被初始化,虚拟机开始初始化,并调用构造方法生成实例对象,所以在执行counter1++; counter2++; 之前,他们两个的值都是0,执行了counter1++; counter2++; 之后为1,1。
而第二种:
private static Singleton obj = new Singleton();
public static int counter1;
public static int counter2 = 0;
虚拟机执行new Singleton(前面和第一种一样)时,首先也检查Singleton类是否被初始化,发现没有被初始化,所以继续初始化,之后开始分配空间创建对象,并执行counter1++; counter2++; 这个时候counter1和counter2都为1,但是private static Singleton obj = new Singleton(); 语句结束之后,前面初始化此类的方法调用还在继续,所以会继续执行
public static int counter1;
public static int counter2 = 0;
所以,counter2 被重新赋值为0.