单例模式容易忽略的几点
程序员文章站
2022-04-04 19:42:49
...
本文意在和谐讨论,高手勿喷~
单例模式容易忽略的几点:
1.第三种单例实现(除了懒汉和饿汉)
2.构造函数私有化(单例的核心)
3.即便构造函数私有化了也不能保证只有一个实例
下面我们来详细阐述:
1.第三种单例实现(除了懒汉和饿汉)
- 饿汉模式无论你是否会用到,上来都会创建实例。
- 懒汉模式只有在用到的时候才会创建,但是为了不产生多线程的问题,需要加synchronized来保证线程安全,但是每次使用的时候都需要带着保证线程安全的操作,无形增加了系统的开销.
于是使用第三种方式(内部类方式)来同时解决懒汉和恶汉的弊端
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)); } }
如果你还知道有什么其他的关于单例"不为人知"的信息,欢迎指教讨论~
转载请保留原文地址!
上一篇: Java 枚举式转码
下一篇: css隐藏元素的方式有哪些