Singleton Invalidated by Clone
If we try to make instance by cloning it, the generated hash code of cloned copy doesn’t match with the actual object so it also violates the Singleton principle.
Example
package com.loopandbreak.singleton; public class SingletonPatternInvalidatedByClone implements Cloneable { private static SingletonPatternInvalidatedByClone singletonPattern = new SingletonPatternInvalidatedByClone(); /* * Constructor is made private */ private SingletonPatternInvalidatedByClone() { System.out.println("Creating Object....."); } public static SingletonPatternInvalidatedByClone getInstance() { return singletonPattern; } // Defining clone method @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { SingletonPatternInvalidatedByClone object1 = SingletonPatternInvalidatedByClone.getInstance(); SingletonPatternInvalidatedByClone object2 = SingletonPatternInvalidatedByClone.getInstance(); print(object1); print(object2); SingletonPatternInvalidatedByClone object3 = (SingletonPatternInvalidatedByClone) object2.clone(); print(object3); } private static void print(SingletonPatternInvalidatedByClone object) { System.out.println("Hashcode of object is " + object.hashCode()); } }
Output
Creating Object..... Hashcode of object is 460141958 Hashcode of object is 460141958 Hashcode of object is 1163157884
How to fix: Throw CloneNotSupportedException from the clone () method if someone tries to make other instance of it.
package com.loopandbreak.singleton; public class SingletonPatternInvalidatedByClone implements Cloneable { private static SingletonPatternInvalidatedByClone singletonPattern = new SingletonPatternInvalidatedByClone(); /* * Constructor is made private */ private SingletonPatternInvalidatedByClone() { System.out.println("Creating Object....."); } public static SingletonPatternInvalidatedByClone getInstance() { return singletonPattern; } // Defining clone method @Override protected Object clone() throws CloneNotSupportedException { // Solution for reflection breaking singleton design pattern if (singletonPattern != null) throw new CloneNotSupportedException(); return super.clone(); } public static void main(String[] args) throws CloneNotSupportedException { SingletonPatternInvalidatedByClone object1 = SingletonPatternInvalidatedByClone.getInstance(); SingletonPatternInvalidatedByClone object2 = SingletonPatternInvalidatedByClone.getInstance(); print(object1); print(object2); SingletonPatternInvalidatedByClone object3 = (SingletonPatternInvalidatedByClone) object2.clone(); print(object3); } private static void print(SingletonPatternInvalidatedByClone object) { System.out.println("Hashcode of object is " + object.hashCode()); } }
Output
Creating Object..... Hashcode of object is 460141958 Hashcode of object is 460141958 Exception in thread "main" java.lang.CloneNotSupportedException at com.loopandbreak.singleton.SingletonPatternInvalidatedByClone.clone(SingletonPatternInvalidatedByClone.java:24) at com.loopandbreak.singleton.SingletonPatternInvalidatedByClone.main(SingletonPatternInvalidatedByClone.java:34)