个人觉得这位博主jvm的文章写的很好,推荐学习jvm的朋友可以看看
package com.yhj.jvm.classloader;
/**
* @Description:单例初始化探究
* @Author YHJ create at 2011-6-4 下午08:31:19
* @FileName com.yhj.jvm.classloader.ClassLoaderTest.java
*/
class Singleton{
private static Singleton singleton=new Singleton();
private static int counter1;
private static int counter2 = 0;
public Singleton() {
counter1++;
counter2++;
}
public static int getCounter1() {
return counter1;
}
public static int getCounter2() {
return counter2;
}
/**
* @Description:实例化
* @return
* @author YHJ create at 2011-6-4 下午08:34:43
*/
public static Singleton getInstance(){
return singleton;
}
}
/**
* @Description: 测试启动类
* @Author YHJ create at 2011-6-4 下午08:35:13
* @FileName com.yhj.jvm.classloader.ClassLoaderTest.java
*/
public class ClassLoaderTest {
/**
* @Description:启动类
* @param args
* @author YHJ create at 2011-6-4 下午08:30:12
*/
@SuppressWarnings("static-access")
public static void main(String[] args) {
Singleton singleton=Singleton.getInstance();
System.out.println("counter1:"+singleton.getCounter1());
System.out.println("counter2:"+singleton.getCounter2());
System.out.println(singleton.getClass().getClassLoader());
}
}
我们调用Singleton singleton=Singleton.getInstance();调用Singleton的静态方法,相当于主动使用了类Singleton,因此Singleton被初始化!
当我们看到显示的是
private static Singleton singleton=new Singleton();
private static int counter1;
private static int counter2 = 0;
这样的时候,顺序执行,先赋予初始值,singleton为null,counter1为0,counter2为0,然后顺序对singleton赋予正确的值new Singleton(),执行构造函数,counter1增加变为1,然后counter2变为1,然后继续执行初始化,将counter2赋值为正确的值,将counter2修改为0,因此运行结果是1、0
反过来
private static int counter1;
private static int counter2 = 0;
private static Singleton singleton=new Singleton();
先赋予初始值counter1为0,counter为0,singleton为null,然后对counter2赋值为正确的值,counter2为0,然后对singleton执行初始化赋予正确的值new Singleton(),执行构造函数,counter1为1,counter2为1,因此执行结果是1、1
我自己试了另外一种情况,即把counter1也把初始值置0 private static int counter1 = 0;第一种情况输入的结果就不是1,0而是
0,0了。因为在初始化阶段如果检查到静态变量有初始值,就会用初始值覆盖原值,而一旦你没有进行初始化,就会保留原来的值。第二种情况输出的结果为1,1,原因就是上面所述。