本文意在和谐讨论,高手勿喷~
?
单例模式容易忽略的几点:
1.第三种单例实现(除了懒汉和饿汉)
2.构造函数私有化(单例的核心)
3.即便构造函数私有化了也不能保证只有一个实例
?
下面我们来详细阐述:
1.第三种单例实现(除了懒汉和饿汉)
于是使用第三种方式(内部类方式)来同时解决懒汉和恶汉的弊端
class="java" name="code">package com.cxy.singleton; /** 内部类方式 * @author cxy */ public class InnerClassSingleton { //私有构造子 (保证整个系统只有一个实例) private InnerClassSingleton(){ System.out.println("InnerClassSingleton 实例化"); } //内部类 private static class SingletonHolder { private static InnerClassSingleton instance = new InnerClassSingleton(); } public static InnerClassSingleton getInstance() { return SingletonHolder.instance; } }
?
?
2.构造函数私有化(单例的核心)
为了保证整个系统只有一份实例,我们使用构造函数私有化的方式来保证,系统不会new出第二个实例。
?
3.即便构造函数私有化了也不能保证只有一个实例
?
其实即便构造函数私有化了,我们还是可以通过反射的方法来new出第二份实例的。
package com.cxy.singleton; import java.lang.reflect.Constructor; import org.junit.Test; public class DestroyTest { @Test public void test() throws Exception { HungrySingleton obj1=HungrySingleton.getInstance(); HungrySingleton obj2=HungrySingleton.getInstance(); System.out.println("obj1和obj2是否相等:"+(obj1==obj2)); System.out.println("====================="); //通过构造方法赋权限 让私有构造函数 可以实例化 HungrySingleton obj3=null; HungrySingleton obj4=null; Constructor[] cons = Class.forName("com.cxy.singleton.HungrySingleton").getDeclaredConstructors(); if(cons.length==1) { cons[0].setAccessible(true); obj3=(HungrySingleton)cons[0].newInstance(); obj4=(HungrySingleton)cons[0].newInstance(); } System.out.println("obj3和obj4是否相等:"+(obj3==obj4)); } }
?
如果你还知道有什么其他的关于单例"不为人知"的信息,欢迎指教讨论~
转载请保留原文地址!