我正在阅读关于Singleton设计模式和评估不同的实现.我怀疑以下的实现:
A.使用静态内部类的单例实现
public class SingletonWithStaticClass { private SingletonWithStaticClass(){} private static class SingletonInnerClass{ public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass(); } public static SingletonWithStaticClass getInstance(){ return SingletonInnerClass.INSTANCE; }
}
B. Singleton双重检查锁定
public class SingletonWithDoubleCheck { private static SingletonWithDoubleCheck INSTANCE = null; private SingletonWithDoubleCheck(){ if(INSTANCE != null){ throw new RuntimeException("Accessing private constructor is prohibited. Use getInstance method instead"); } } public static SingletonWithDoubleCheck getInstance(){ if(INSTANCE == null){ synchronized (SingletonWithDoubleCheck.class) { if(INSTANCE == null){ INSTANCE = new SingletonWithDoubleCheck(); } } } return INSTANCE; }
}
哪一个更好?
我觉得我们可以在第一个实现中使用Reflection访问私有构造函数,其中第二个实现是安全的(From Reflection攻击).
但是,我不会在我的生产代码中使用任何这些,我将使用枚举.但是出于这两个,当考虑反射攻击时,是不是第一个实现被破坏?
如果我的理解是错误的,请纠正我.
两者都过于复杂.第一个是Java 5.0之前的最佳选择,但第二个从来都不是一个好选择.它在Java 5.0之前不起作用,它需要一个volatile
字段,在此版本之后你可以使用它enum
我更喜欢使用an enum
来定义一个只有一个实例的类.它是一个final
类,线程安全,延迟加载,并有一个private
构造函数.
enum Singleon { INSTANCE; }
双锁定单例仅在必须在其构造中提供配置信息时才有用.在这种情况下,我更喜欢使用依赖注入来提供/配置单例,并且只使用不需要配置的无状态单例.