I'm new to java and was studying object cloning. My question is that since Object class is the top most class in java and all other classes inherits this class and clone() method is defined in the Object class, then what is purpose of using cloneable interface? Why can't we just override the clone() method of Object class in our class and return super.clone() from it(or modify it for deep copy according to our needs)?
Also which is the recommended way (java standard way) of creating clones of the object? Using clone() method or creating copy constructor just like C++ which is mentioned in Andreas dolk's answer to this question?
The clone
situation is unique and is rather anti-java-like - there's a reason its not recommended to use it in the first place. The way Cloneable
is used in the JDK is not something you should be taking notes on - this isn't how to design APIs, nothing else in the java ecosystem works this way.
Weirdly, this is a common thing: The core parts of java often aren't java-like. For example, nobody in their right mind would make an API that defines an application by 'it has a method with the signature public static void main(String[] args)
. The obvious design principle would be to make an abstract class or interface with an abstract start()
method, and to make a java app you write a class that has a no-args constructor and implements/extends that interface/class. Same story for arrays: They are weird - their toString, equals, and hashCode implementations are surprising, to say the least. They aren't entirely type-safe either.
The reasons for all of this are historic: To explain them, you need to know about all sorts of things that were relevant at the time, but aren't important anymore and haven't been for decades.
Cloneable is no different. Let me explain why it works that way:
The 'system' of cloning is offered by the JDK itself, it's a built-in thing that an ordinary library could not easily make. Kinda how "java SomeClass
invokes its main method" is part of java itself.
The system, however, needs an opt-in mechanism: The act of cloning may not make sense (what does it mean to 'clone' an InputStream
representing a TCP network connection's incoming bytes? What does it mean to 'clone' the value of an enum which tries to guarantee that only one instance ever exists? What does it mean to 'clone' a singleton?)
Thus, 'just make all objects cloneable' is dangerous, so java didn't want to do that: They want you to opt in to it. Java wants the author of a class to explicitly say: Yup. I am clonable, using the standard mechanism (which deep-copies all fields, if memory serves).
That is what Cloneable
is for! - that's how you say: Yup. I'm good with it. By implementing that. It's a flag.
Java could also have decided to do something like:
/** @cloneable */
public class Something {}
instead, but they didn't. If it had been designed in this more modern age, perhaps it would have looked like:
@Cloneable
public class Something {}
But annotations were introduced in java 1.5 as a demo feature in 1.6 properly. The cloneable interface is as old as java 1.0 - over a decade earlier. "add an interface that defines nothing" was the standard way to flag class properties back then, even if it isn't now.
NB: You don't just implements Cloneable
, you also make a public clone method. The implements Cloneable
part tells the cloning system: You may clone this class, for example even if it is part of the deep structure of an encompassing object that is being cloned. Making a clone method that invokes the protected JVM-provided clone()
method that j.l.Object
has is how you expose the API. Maybe you want to name it copy
instead, or maybe you want cloning but not as part of your public
API. Your question isn't about how to use clone, but why it works like it is - my advice if you want to use it is simple. Don't, write clone code yourself, or better yet, design your API with more immutables so that cloning is no longer neccessary.