概述
在单例模式的实现中,除去 枚举 方法实现的单例模式,其它的实现都可以利用反射构造新的对象,从而破坏单例模式,但是枚举就不行,下面说说原因:
破坏单例的方式有 3 种,反射、克隆以及序列化,下面详细介绍:
1. 反射
常见的单例模式实现中,往往有一个私有的构造函数,防止外部程序的调用,但是通过反射可以轻而易举的破坏这个限制:
public class DobleCheckSingleton {
private DobleCheckSingleton(){
}
private static volatile DobleCheckSingleton dobleCheckSingleton;
public static DobleCheckSingleton getSingleton(){
if (dobleCheckSingleton == null){
synchronized (DobleCheckSingleton.class){
if (dobleCheckSingleton == null){
dobleCheckSingleton = new DobleCheckSingleton();
}
}
}
return dobleCheckSingleton;
}
public static void main(String[] args) {
try {
DobleCheckSingleton dobleCheckSingleton = DobleCheckSingleton.getSingleton();
Constructor<DobleCheckSingleton> constructor = DobleCheckSingleton.class.getDeclaredConstructor();
constructor.setAccessible(true);
DobleCheckSingleton reflectInstance = constructor.newInstance();
System.out.println(dobleCheckSingleton == reflectInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出:false,单例被破坏
而通过枚举实现的单例模式,利用反射构造新的对象,由于 enum 没有无参构造器,结果会抛出 NoSuchMethodException 异常
public enum EnumSingleton {
INSTANCE;
public static void main(String[] args) {
try {
EnumSingleton enumSingleton = EnumSingleton.INSTANCE;
// 获取无参的构造函数
Constructor