在Singleton设计模式中,如果我创建单个类对象的克隆,并打印两个对象,我得到两个不同的输出,但构造函数只被调用一次。我很困惑,天气Singleton设计模式在这种情况下失败还是只是一种错觉?
public class LazySingleton implements Cloneable{
private static LazySingleton lazy;
private static int counter=0;
private LazySingleton() {
System.out.println(counter++);
}
public synchronized static LazySingleton getObject(){
if(lazy==null)
lazy=new LazySingleton();
return lazy;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public class DriverClone {
public static void main(String[] args) throws CloneNotSupportedException {
LazySingleton obj=LazySingleton.getObject();
System.out.println(obj);
System.out.println(obj.clone());
}
}
输出
0
LazySingletonDesignPattern.LazySingleton@157ee3e5
LazySingletonDesignPattern.LazySingleton@3da3da69
答案 0 :(得分:0)
单例模式不是JVM提供的。 JVM对Singleton一无所知,开发人员希望它只出现一次。它只是一种模式,没有内置的JVM功能。
当然,有一些方法可以复制Singleton,例如,使用Reflection
API。没有什么能阻止开发者克隆你的Singleton(in case it's not an enum)。
正如您发布的那样,clone()
也可以使用。在您的示例中,您确实生成了两个不同的对象。但是,为了防止克隆,覆盖clone()
并抛出CloneNotSupportedException
或多或少的常见做法。
答案 1 :(得分:0)
问题出现在你使单身克隆的地方:
public class LazySingleton implements Cloneable
对于单身人士没有理由这样做,因为根据定义,只有一个单身人士的实例。
不要实施Cloneable
,然后无法克隆(至少通过调用clone()
)。