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)
Share

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *