51

I am not fully understanding the idea of returning super.clone() in the clone() method of a class. First of all, wouldn't that relate to it returning an object that is a superclass which contains LESS data than requested, because a superclass "is not a" subclass, but a subclass "is a" superclass. And if there were a long chain of subclasses, each calling super.clone(), why wouldn't that lead to it eventually calling Object.clone() at the root of the chain, which isn't any of the subclasses?

Sorry if that was confusing; I confuse myself sometimes

TurtleToes
  • 2,047
  • 2
  • 17
  • 17
  • 2
    http://stackoverflow.com/questions/2156120/java-recommended-solution-for-deep-cloning-copying-an-instance/2156367#2156367 – Bozho Mar 25 '11 at 10:11
  • this is the most confusing asked by someone, however answer is as simplified as it can be.. – Narendra Jaggi Apr 03 '20 at 18:10

3 Answers3

60

The implementation of clone() in Object checks if the actual class implements Cloneable, and creates an instance of that actual class.

So if you want to make your class cloneable, you have to implement Cloneable and downcast the result of super.clone() to your class. Another burden is that the call to super.clone() can throw a CloneNotSupportedException that you have to catch, even though you know it won't happen (since your class implements Cloneable).

The Cloneable interface and the clone method on the Object class are an obvious case of object-oriented design gone wrong.

Laurent Pireyn
  • 6,735
  • 1
  • 29
  • 39
  • 2
    I keep reading that I should avoid using clone(), but I want to at least understand how it works... it's driving me nuts – TurtleToes Mar 25 '11 at 10:11
  • 4
    @TurtleToes: If all ancestral classes implement clone using Super.Clone, then derived classes should either override clone with a version that uses super.clone, or else simply let derived classes inherit the existing clone method. If any ancestral classes instead implement it using a copy constructor, then *all* derived classes will have to use a copy constructor as well; using the inherited clone method would not be an option in that case. – supercat Aug 25 '11 at 04:07
  • '(...) and creates an instance of that actual class'. Without calling a constructor says the spec in `Object#clone()`; magic is involved, I guess. – ᴠɪɴᴄᴇɴᴛ Aug 27 '20 at 15:09
  • 1
    Why is this the accepted answer? It doesn't explain any reason. It just repeats what you have to do and not the reason why. I think Cloneable is 100% crap and just write a copy() method to copy my object... – The incredible Jan Dec 07 '20 at 14:51
7

Consider this: you have a chain of inheriting classes. each may (or may not) have its own variables. what clone does, as opposed to the equals operator (==) that duplicates the reference, is a cloned copy of the object with a new reference. For the example above, you would like to clone the last object in the chain. As the last object is constructed of its superclasses, where each may have a different cloning method implementation, it makes a lot of sense to call the superclass implementation of clone to receive first a cloned parent object before cloning own object.

Another terms that are usually associated with cloning is shallow and deep cloning. shallow cloning refer to the creation of an exact replica of an object, while deep cloning creates a replica of an object and any child object that the original object refers to.

More on cloning at this link

Assaf Adato
  • 237
  • 4
  • 14
  • If I have a class that implements Cloneable, and it has subclasses that have a clone() function, those subclasses do not need to implement Cloneable also? Is that because the interface is derived from the superclass? Also, the subclass does not need to try for the exception, I am assuming because the superclass is already trying for it and is not throwing one? Is this right? – TurtleToes Mar 25 '11 at 10:40
  • if a superclass implements cloneable, all its subclasses automatically implements cloneable as well and there is no need to explicitly specify this implementation. As for your second Q, not sure I understand the wording: "try for the exception". can you clarify? – Assaf Adato Mar 25 '11 at 16:21
  • in the direct subclass of object, you must implement a try block to catch the exception thrown by Object.clone(). It won't let you not check for it. However, a subclass of this subclass doesn't need to check for the exception when calling super.clone() like the superclass did. – TurtleToes Mar 25 '11 at 17:17
  • This is not correct. The exception handling is required whenever you call super.clone() regardless of your location in the inheritance tree. e.g. you have 3 classes: UpperMostClass implements Cloneable, ParentClass extends UpperMostClass, and ChildClass extends ParentClass. As they are all Cloneable, each call to super.clone() requires handling as CloneNotSupportedException is a checked exception. does it may sense to you? – Assaf Adato Mar 26 '11 at 07:02
5

Read the javadoc of Object.clone() more carefully : it returns a copy of the object. The copy is another instance of the same class as that of the object on which clone is invoked. I.e. foo.clone().getClass() == foo.getClass().

trss
  • 915
  • 1
  • 19
  • 35
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255