这个单例对象产生的时机不一样。前者在 Singleton 类初始化后 sInstance 对象就创建了,也就是说在调用 getInstance 之前。后者在调用 getInstance 时,SingletonHolder.holder 对象尚未创建,因为 SingletonHolder 类还没有初始化,当执行到 SingletonHolder. 加载 SingletonHolder 类后 holder 对象开始初始化工作

解决方案 »

  1.   

    (楼上又回来了?)
    Java 中类的加载本身是“延迟”的,当你第一次在代码中提到 Singleton 这个类的时候,它才被加载,内部类也是一样的。换句话说,对于第一种,假如你不调用  Singleton.getInstance(); 而是写:Class<?> singletonType = Singleton.class;那 sInstance 也会被建立。
    而 Singleton.SingletonHolder 则不同,SingletonHolder 是 private 的内部类,提到它的唯一的地方在 getInstance() 方法内,所以只有第一次运行 Singleton.getInstance() 方法的时候它才会被加载,而作为它静态成员的 holder 才会被建立。其实多数情况下一个被设计成单例的类,你第一次提到它的类名一般就是要调用 getInstance() 方法,一般单例的类也只有这一个静态方法,所以第一种就行了。
      

  2.   


    请问只有在 Class<?> singletonType = Singleton.class; 即反射的时候才会有区别吗? 这两种形式还有其他区别吗?谢谢
      

  3.   


    bao110908 说:
    前者在 Singleton 类初始化后 sInstance 对象就创建了,也就是说在调用 getInstance 之前。你的解释和我的理解都认为 前者也是在调用getInstance 时才进行初始化。 不是这样吗?
      

  4.   


     这是你的理解,我可没这么说我说的是换句话说,对于第一种,假如你不调用  Singleton.getInstance(); 而是写:Class<?> singletonType = Singleton.class;那 sInstance 也会被建立。
      

  5.   

    I am totally confused. 这样理解对吗?
    假设 Singleton.getInstance() 是代码中第一句提到Singleton class的地方。那么这两种初始化类的方式没有区别。谢谢。
      

  6.   

    单例的是否懒加载,也就是单例对象的创建时机的问题.
    懒加载, 也就是在不调用getlnstance()方法的时候,Singleton 对象是不创建的.
    非懒加载,就是只要主动使用了Singleton ,对象就会被创建.你的第一个例子,sInstance变量被定义为static类型的,所以第一次主动使用Singleton类的时候,sInstance就会被初始化,也就是单例对建被创建了出来.也即非懒加载.所以区别就在于对象是什么时候被创建的.至于各自的好处,楼主可以自己理解啊,什么时候要懒加载,它是根据你的需要而定的.如果创建对象不是消耗很大的话,区别并不明显。
      

  7.   

    貌似Singletion.class这个是类字面常量,根本就不会引起类加载,请回家好好看看《Tinking in Java》,然后再打开IDE调试一下再来发表言论,发现论坛里面都是转来转去,又有几个人自己调试过呢
      

  8.   

    但是,final static这样的常量,在编译阶段就已经存入class文件的常量池中,那是不是说,再编译阶段就已经初始化完成了?还是说,分配实例对象的步骤要到调用getlnstance(),编译阶段只是定义其应用类型?