2

Using the clone method, can we get many instances of a class which has been made singleton ?

Also, is it necessary to write "implements Cloneable" because I learnt that all objects extend from Object class and hence the child object calling protected clone() on another child of Object should have no access issues

Prabhat Gaur
  • 146
  • 1
  • 10
  • 1
    I don't think so, as the purpose of the singleton is to encapsulate itself, bearing its memory reference. So if you shallow-clone it, you might be able to create a new reference for it, but the memory reference within the singleton will probably be the same as previous. – DamCx Jul 04 '18 at 08:17
  • 1
    If a singleton class provides a clone method, it defeats its own purpose. – f1sh Jul 04 '18 at 08:17
  • The singleton class need not provide one implementation of clone according to https://stackoverflow.com/questions/30207940/what-happens-to-protected-method-of-a-super-class-in-base-class-in-java – Prabhat Gaur Jul 04 '18 at 13:00

3 Answers3

4

It won't happen until you implement Cloneable by your singleton (which is an anti-pattern as it contradicts the very purpose of singleton). So, it can only happen if you do something like this:

SomeClass.java

class SomeClass implements Cloneable {
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

Singleton.java

class Singleton extends SomeClass {
    public static Singleton instance = new Singleton();
    private Singleton() {}
}

Main.java

class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        Singleton singleton1 = Singleton.instance;
        Singleton singleton2 = singleton1.clone();
        System.out.println("singleton1 : "
                       + singleton1.hashCode());
        System.out.println("singleton2 : "
                       + singleton2.hashCode()); 
    }
}    

Output

singleton1 : 445884362

singleton2 : 1793329556

Even this in this case, you can solve this issue by overriding clone in Singleton and throwing an exception.

Community
  • 1
  • 1
Anatolii
  • 14,139
  • 4
  • 35
  • 65
3

The Java-Doc says about Object.clone():

Creates and returns a copy of this object. The precise meaning of "copy" may depend on the class of the object.

It depends on your implementation of the clone() method what kind of copy or clone you get. But the Java-Doc says further:

By convention, the object returned by this method should be independent of this object (which is being cloned).

Following this convention a clone would be another independent instance of something that was a singleton instance before.

Going on with the Java-Doc:

The class Object does not itself implement the interface Cloneable, so calling the clone method on an object whose class is Object will result in throwing an exception at run time.

So you have to explicitly declare that your class implements Cloneable. As long as you don't do it, there is no public clone() method on your instance. But you wouldn't do that for a singleton since this would render your class design (singleton) useless.

If you did not declared the singleton class final and extends it with another class which an instance of would call super.clone() this will throw the mentioned CloneNotSupportedException.

If you would explicitlly declare that your singleton class implements Cloneable according to the Java-Doc this:

creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.

To get a proper clone the Java-Doc of Cloneable says:

... classes that implement this interface should override Object.clone ... Therefore, it is not possible to clone an object merely by virtue of the fact that it implements this interface.

So you really have to do it explicit.


Answering the question:
Is it possible? Yes it is - but only if you allow it.
Is it intended? No.

Also note:
Beside the mentioned above by using reflection you could try to bypass the visibility restrictions of a singleton class to create further instances.

LuCio
  • 5,055
  • 2
  • 18
  • 34
  • Does shallow cloning really give independent object or is it that the member objects inside it will point to original member objects? – Prabhat Gaur Jul 04 '18 at 08:40
  • You still wrote that cloning gives independent object. You also mention that object has no implementation of clone method which I doubt because of super.clone() everywhere. Sir please elaborate about subclass implementing protected interface – Prabhat Gaur Jul 04 '18 at 09:07
  • Sorry, I don't understand what you mean by "_implementing protected interface_" and "_superclone() everywhere_". `Cloneable`isn*t a protected interface. – LuCio Jul 04 '18 at 09:12
  • I mean to say that object class already has protected implementation of clone method so why do we write super.clone() – Prabhat Gaur Jul 04 '18 at 09:18
  • First of all a singleton class (as every class which does not extend explicit another class) is extending directly the class `Object`. So if you want to clone the singleton you need to to call `super.clone()` to do the baisc cloning performed by the `Object` as stated in the last excerpt of Java-Doc above. And if you have further subclasses of your singleton they all have to call `super.clone()` the whole inheritence hierarchy upwards. – LuCio Jul 04 '18 at 09:24
0

First, never use clone. See here

Second, clone do shallow copy. See here

Last, suggest to use enum for singleton, which is guarantee by VM. See here

Dean Xu
  • 4,438
  • 1
  • 17
  • 44