我正在阅读单例设计模式并评估不同的实现。我对以下实现有疑问:
A.静态内部类的单例实现
public class SingletonWithStaticClass {
private SingletonWithStaticClass(){}
private static class SingletonInnerClass{
public static SingletonWithStaticClass INSTANCE = new SingletonWithStaticClass();
}
public static SingletonWithStaticClass getInstance(){
return SingletonInnerClass.INSTANCE;
}
}
B.单例双重检查锁定
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;
}
哪个更好?
我觉得我们可以在第一个实现中使用反射访问私有(private)构造函数,而第二个实现是安全的(来自反射攻击)。
但是,我不会在我的生产代码中使用任何这些,我将使用 enum 代替。但是在这两个中,当考虑反射攻击时,第一个实现不是被破坏了吗?
如果我的理解有误,请指正。
最佳答案
两者都过于复杂。第一个是 Java 5.0 之前的最佳选择,但是第二个从来都不是一个好的选择。它在 Java 5.0 之前不起作用,它需要一个 volatile
字段,在此版本之后你可以使用 enum
我更喜欢使用 enum
来定义一个只有一个实例的类。它是一个 final
类,线程安全,延迟加载,并且有一个 private
构造函数。
enum Singleon {
INSTANCE;
}
双重锁定单例仅在您必须在其构造中提供配置信息时才有用。在这种情况下,我更喜欢使用依赖注入(inject)来提供/配置单例,并且只有不需要配置的无状态单例。
关于java - 具有静态内部类和双重检查锁定的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34512725/