В шаблоне проектирования 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




Шаблон Singleton - это не то, что предоставляет JVM. JVM ничего не знает о синглтоне и о том, что разработчик намеревается, что он будет присутствовать только один раз. Это просто шаблон, а не встроенная функция JVM.
Конечно, есть способы дублировать синглтон, например, с помощью API Reflection. Ничто не помешает разработчику клонировать ваш синглтон (в случае, если это не перечисление).
Как вы писали, clone() тоже можно использовать. В вашем примере вы действительно создали два разных объекта. Однако для предотвращения клонирования более или менее распространенной практикой является переопределение clone() и выдача CloneNotSupportedException.
Проблема возникает, когда вы делаете клонируемый синглтон:
public class LazySingleton implements Cloneable
Нет причин делать это для синглтона, поскольку по определению существует только один экземпляр синглтона.
Не реализуйте Cloneable, тогда его нельзя будет клонировать (по крайней мере, с помощью clone()).