How does clone() method in java works? - java

I know this question has been asked so many times.
First of all Object.clone() method in java is native method i.e. it is implemented in JVM and user doesn't need to know about it's implementation.
My question is whether this method is abstract too. If not why it has to be overridden in the class that we want to clone.
And one more question .
It is overridden as follows
public Object clone() {
MyClass obj;
try {
obj = (MyClass)super.clone();
} catch(CloneNotSupportedException e) {
Statements
}
return obj;
}
In the 4th line of this code we called , super.clone() method , which clone() method are we calling in this line and if Object.clone() method why did we override it , we can simply cast it wherever we want to clone the Object like
MyClass obj2 = (MyClass)obj1.clone();
and is their any way to know the coding of Object.clone() method?

A method cannot be native and abstract at the same time because native is a statement about a specific implementation of a method;
clone must be overridden at least because Object#clone is protected to prevent access to clients in the case the object does not support cloning;
in many cases clone needs to do more than Object#clone, which just makes a binary copy of the original, which amounts to a shallow clone, with all the referenced objects staying the same;
there's no point in catching CloneNotSupportedException in the subclass: you should already know whether the superclass does or doesn't support cloning (it is not something which can change at runtime).

Object.clone() is not abstract. Overriding it when implementing Clonable is just a convention. (Clonable is a marker interface - like Serializable etc.)
Overriding methods (should) always call Object.clone() directly or indirectly.
I think, casting it is not necessary because Object.clone() preserves the exact class. If you catch the CloneNotSupportedException you could even return MyClass.
As Object.clone() is implemented natively you would have to look at the sources of some JVM implementation like OpenJDK.

My question is whether it's abstract too
No it isn't, and the Javadoc already tells you that, as does the fact that Object itself isn't abstract, and it 'doesn't have to be overridden in the class we want to clone' unless you want to change the access permission, which has nothing to do with 'abstract': and you couldn't call 'super.clone()' in such an override unless it wasn't abstract.
In short, your question doesn't make much sense.

Related

What limits clone() from being accessible for all objects? [duplicate]

What is the specific reason that clone() is defined as protected in java.lang.Object?
The fact that clone is protected is extremely dubious - as is the fact that the clone method is not declared in the Cloneable interface.
It makes the method pretty useless for taking copies of data because you cannot say:
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
I think that the design of Cloneable is now largely regarded as a mistake (citation below). I would normally want to be able to make implementations of an interface Cloneable but not necessarily make the interface Cloneable (similar to the use of Serializable). This cannot be done without reflection:
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Citation From Josh Bloch's Effective Java:
"The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be emulated ... In order for implementing the interface to have any effect on a class, it and all of its superclasses must obey a fairly complex, unenforceable and largely undocumented protocol"
The Clonable interface is just a marker saying the class can support clone. The method is protected because you shouldn't call it on object, you can (and should) override it as public.
From Sun:
In class Object, the clone() method is declared protected. If all you do is implement Cloneable, only subclasses and members of the same package will be able to invoke clone() on the object. To enable any class in any package to access the clone() method, you'll have to override it and declare it public, as is done below. (When you override a method, you can make it less private, but not more private. Here, the protected clone() method in Object is being overridden as a public method.)
clone is protected because it is something that ought to be overridden so that it is specific to the current class. While it would be possible to create a public clone method that would clone any object at all this would not be as good as a method written specifically for the class that needs it.
The Clone method can't be directly used on any object, which is why it is intended to be overriden by the subclass.
Of course it could be public and just throw an appropriate exception when cloning is not possible, but i think that would be misleading.
The way clone is implemented right now makes you think about why you want to use clone, and how you want your object to be cloned.
IMHO it's as simple as this:
#clone must not be called on non-cloneable objects, therefore it is not made public
#clone has to be called by subclasses ob Object that implement Cloneable to get the shallow copy of the right class
What's the right scope for methods that shall be callable by subclasses, but not by other classes?
It's protected.
Classes implementing Cloneable of course will make this method public so it can be called from other classes.
It is protected because the default implementation does a shallow memberwise copy of all fields (including private), circumventing constructor. This is not something an object might be designed to handle in the first place (for example, it might keep track of created object instances in a shared list, or something similar).
For the same reason, the default implementation of clone() will throw if the object it's called on doesn't implement Cloneable. It's a potentially unsafe operation with far-reaching consequences, and therefore author of the class must explicitly opt-in.
From the javadoc of cloneable.
* By convention, classes that implement this interface (cloneable) should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {#link java.lang.Object#clone()} for details on overriding this
* method.
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
So you could call clone on every object but this would give you most of the time not the results you want or an exception. But is only encouraged if you implement cloneable.
Clone() method has a check internally 'instance of Cloneable or not'.This is how Java team might thought will restrict the improper use of clone() method.clone() method is protected i.e. accessed by subclasses only. Since object is the parent class of all sub classes, so Clone() method can be used by all classes infact if we don't have above check of 'instance of Cloneable'. This is the reason Java team might have thought to restrict the improper use of clone() by having the check in the clone() method 'is it instance of Cloneable'.
Hence whatever classes implement cloneable can use clone() method of Object class.
Also since it made protected, it is available to only those sub classes that implements cloneable interface. If we want to make it public, this method has to be overridden by the sub class with their own implementation of it.
Yes, same problem that I met.
But I solve it by implementing this code
public class Side implements Cloneable {
public Side clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
}
return side;
}
}
Just as the before someone said.
Well, also the sun developers are only human, and they did indeed make huge mistake to implement the clone method as protected, the same mistake as they implemented a non-functioning clone method in ArrayList! So, in general, there exist a much deeper misunderstanding of even experienced Java programmers about the clone method.
However, I've recently found a fast and easy solution to copy any object with all its content, no matter how it is built and what it contains, see my answer here: Bug in using Object.clone()
Again, Java JDK framework shows brilliant thinking:
Cloneable interface does not contain a "public T clone();" method because it acts more like an attribute (eg. Serializable) which allows an instance it to be cloned.
There is nothing wrong with this design because:
Object.clone() will not do what you want with your custom-defined class.
If you have Myclass implements Cloneable => you overwrite clone() with
"public MyClass clone()"
If you have MyInterface extends Cloneable and some MyClasses implementing MyInterface:
simply define "public MyInterface clone();" in the interface and every method using MyInterface objects will be able to clone them, no matter their MyClass-class.

Why no default clone() in Cloneable in Java 8

Cloneable in Java is inherently broken. Specifically, my biggest problem with the interface is it expects a method behavior that doesn't define the method itself. So if traversing through a Cloneable list you must use reflection to access its defined behavior. However, in Java 8, we now have default methods and now I ask why there isn't a default clone() method in Cloneable.
I understand why interfaces cannot default Object methods, however, this was an explicit design decision and so exceptions can be made.
I sort of envision deprecating Object.clone() and changing its interior code to something like:
if(this instanceof Cloneable) {
return ((Cloneable) this).clone();
}
else {
throw new CloneNotSupportedException();
}
And moving on whatever magic makes clone() do its thing as a default method in Cloneable. This doesn't really fix that clone() can still easily be implemented incorrectly, but that's another discussion in of itself.
As far as I can still this change would be completely backwards compatible:
Classes that currently override clone() but didn't implement Cloneable (WHY?!) would still be technically okay (even if functionally impossible, but this is no different then it was before).
Classes that currently override clone(), but did implement Cloneable would still function the same on its implementation.
Classes that don't currently override clone(), but did implement Cloneable (WHY?!) would now follow a specification, even if it's not completely functionally correct.
Those that used reflection and referred to Object.clone() would still functionally work.
super.clone() would still be functionally the same even if it's referencing Object.clone().
Not to mention this would solve a huge problem that Cloneable is. While tedious and still easy to implement incorrectly, it would solve a huge object oriented problem with the interface.
The only problem I can see with this is those that implement Cloneable aren't obligated to override clone(), but this is no different than it was before.
Has this been discussed internally, but never came to fruition? If so, why? If it's for the reason that interfaces cannot default Object methods, wouldn't it make sense to make an exception in this case since all objects inheriting Cloneable are expecting clone() anyway?
Your question is somewhat broad and more of a discussion, but I can shed some light on this matter.
In Effective Java™, Joshua Bloch gives quite the rundown on the situation. He opens with a bit of history behind Cloneable
The Cloneable interface was intended as a mixin interface for objects to
advertise that they permit cloning. Unfortunately, it fails to serve this purpose. Its primary flaw is that it lacks a clone method, and Object’s clone method is protected. You cannot, without resorting to reflection, invoke the clone method on an object merely because it implements Cloneable.
and continues with the reasoning
[Cloneable] determines the behavior of Object’s protected clone implementation: if a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object... This is a highly atypical use of interfaces and not one to be emulated. Normally, implementing an interface says something about what a class can do for its clients. In the case of Cloneable, it modifies the behavior of a protected method on a superclass.
and
If implementing the Cloneable interface is to have any effect on a class, the
class and all of its superclasses must obey a fairly complex, unenforceable, and
thinly documented protocol. The resulting mechanism is extralinguistic: it creates an object without calling a constructor.
There are a lot of details that go into this, but to note just one problem:
The clone architecture is incompatible with normal use of final fields referring to mutable objects.
I think this is enough to reason against having a default method in the interface do the cloning. It would be extremely complicated to implement it correctly.
My experience is probably far from being mainstream, but I use clone() and support the current design of Cloneable. Probably it would be better to have it as annotation instead, but Cloneable appeared long before the annotations. My opinion is that Cloneable is a low-level thing and nobody should do something like obj instanceof Cloneable. If you are using Cloneable in some business-logic, it's much better to declare your own interface or abstract class which exposes clone() to public and implement it in all of your business-logic objects. Sometimes you will probably want not to expose clone() actually, but create your own method which uses clone() internally.
For example, consider that you have an hierarchy of named objects where name cannot be changed after construction, but you want to allow cloning them with new name. You can create some abstract class like this:
public abstract class NamedObject implements Cloneable {
private String name;
protected NamedObject(String name) {
this.name = name;
}
public final String getName() {
return name;
}
public NamedObject clone(String newName) {
try {
NamedObject clone = (NamedObject)super.clone();
clone.name = newName;
return clone;
}
catch(CloneNotSupportedException ex) {
throw new AssertionError();
}
}
}
Here even though you implement Cloneable, you want to use clone(), but don't want to expose it publicly. Instead you provide another method which allows to clone with another name. So having public clone() in Cloneable would unnecessarily pollute the public interface of your classes.
Another case where I use Cloneable is the implementation of Spliterator.trySplit(). See the implementation of simple spliterator which returns given number of constant objects. It has four specializations (for Objects, ints, longs and doubles), but thanks to clone() I can implement trySplit() only once in the superclass. Again, I don't want to expose clone(), I just want to use it by myself.
So to conclude, not having clone() method in Cloneable interface is actually more flexible as it allows me to decide whether I want to have it public or not.

why object clone method is protected not public? [duplicate]

What is the specific reason that clone() is defined as protected in java.lang.Object?
The fact that clone is protected is extremely dubious - as is the fact that the clone method is not declared in the Cloneable interface.
It makes the method pretty useless for taking copies of data because you cannot say:
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
I think that the design of Cloneable is now largely regarded as a mistake (citation below). I would normally want to be able to make implementations of an interface Cloneable but not necessarily make the interface Cloneable (similar to the use of Serializable). This cannot be done without reflection:
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Citation From Josh Bloch's Effective Java:
"The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be emulated ... In order for implementing the interface to have any effect on a class, it and all of its superclasses must obey a fairly complex, unenforceable and largely undocumented protocol"
The Clonable interface is just a marker saying the class can support clone. The method is protected because you shouldn't call it on object, you can (and should) override it as public.
From Sun:
In class Object, the clone() method is declared protected. If all you do is implement Cloneable, only subclasses and members of the same package will be able to invoke clone() on the object. To enable any class in any package to access the clone() method, you'll have to override it and declare it public, as is done below. (When you override a method, you can make it less private, but not more private. Here, the protected clone() method in Object is being overridden as a public method.)
clone is protected because it is something that ought to be overridden so that it is specific to the current class. While it would be possible to create a public clone method that would clone any object at all this would not be as good as a method written specifically for the class that needs it.
The Clone method can't be directly used on any object, which is why it is intended to be overriden by the subclass.
Of course it could be public and just throw an appropriate exception when cloning is not possible, but i think that would be misleading.
The way clone is implemented right now makes you think about why you want to use clone, and how you want your object to be cloned.
IMHO it's as simple as this:
#clone must not be called on non-cloneable objects, therefore it is not made public
#clone has to be called by subclasses ob Object that implement Cloneable to get the shallow copy of the right class
What's the right scope for methods that shall be callable by subclasses, but not by other classes?
It's protected.
Classes implementing Cloneable of course will make this method public so it can be called from other classes.
It is protected because the default implementation does a shallow memberwise copy of all fields (including private), circumventing constructor. This is not something an object might be designed to handle in the first place (for example, it might keep track of created object instances in a shared list, or something similar).
For the same reason, the default implementation of clone() will throw if the object it's called on doesn't implement Cloneable. It's a potentially unsafe operation with far-reaching consequences, and therefore author of the class must explicitly opt-in.
From the javadoc of cloneable.
* By convention, classes that implement this interface (cloneable) should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {#link java.lang.Object#clone()} for details on overriding this
* method.
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
So you could call clone on every object but this would give you most of the time not the results you want or an exception. But is only encouraged if you implement cloneable.
Clone() method has a check internally 'instance of Cloneable or not'.This is how Java team might thought will restrict the improper use of clone() method.clone() method is protected i.e. accessed by subclasses only. Since object is the parent class of all sub classes, so Clone() method can be used by all classes infact if we don't have above check of 'instance of Cloneable'. This is the reason Java team might have thought to restrict the improper use of clone() by having the check in the clone() method 'is it instance of Cloneable'.
Hence whatever classes implement cloneable can use clone() method of Object class.
Also since it made protected, it is available to only those sub classes that implements cloneable interface. If we want to make it public, this method has to be overridden by the sub class with their own implementation of it.
Yes, same problem that I met.
But I solve it by implementing this code
public class Side implements Cloneable {
public Side clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
}
return side;
}
}
Just as the before someone said.
Well, also the sun developers are only human, and they did indeed make huge mistake to implement the clone method as protected, the same mistake as they implemented a non-functioning clone method in ArrayList! So, in general, there exist a much deeper misunderstanding of even experienced Java programmers about the clone method.
However, I've recently found a fast and easy solution to copy any object with all its content, no matter how it is built and what it contains, see my answer here: Bug in using Object.clone()
Again, Java JDK framework shows brilliant thinking:
Cloneable interface does not contain a "public T clone();" method because it acts more like an attribute (eg. Serializable) which allows an instance it to be cloned.
There is nothing wrong with this design because:
Object.clone() will not do what you want with your custom-defined class.
If you have Myclass implements Cloneable => you overwrite clone() with
"public MyClass clone()"
If you have MyInterface extends Cloneable and some MyClasses implementing MyInterface:
simply define "public MyInterface clone();" in the interface and every method using MyInterface objects will be able to clone them, no matter their MyClass-class.

Return type ambiguity

Consider the following code from The Java Programming Language book
public class MyClass extends HerClass implements Cloneable {
public MyClass clone()
throws CloneNotSupportedException {
return (MyClass) super.clone();
}
// ...
}
When the overiding clone() function already species the return type as MyClass then what is the requirement of specifying it again in the return statement ?
Also since the clone of Myclass's super class object is being created (cause clone() is being called wrt superclass), how can it be of Myclass type?
Thanks in advance
Because clone() returns an object of class Object, and you must cast it to the correct type. But you know it is an object of type MyClass, so that cast is correct.
In theory you're right: as you have to specify the type of function return values the compiler could try and perform the correction automatically. On the other hand requiring an explicit conversion helps identify possible errors.
Unless you have specific requirements the clone() method of the Object class already does the right thing, i.e. it creates an object of the correct class and copies all the non-static attributes in the cloned object. However it cannot return it as a derived type because at compile time that type is not known to the Object class itself.
It is true that the clone() method could have been provided automatically for all classes, but sometimes you don't want it to be available and at other times you want to override the default behaviour; for instance you might have an id attribute in your class that you want to be different for each instance of your class even when cloned. Having to override the clone() method gives you a place where you can implement such functionality.
This is because the clone() method in Object returns an Object. However you can return your subclass in clone() because it extends an Object. If the method in MyClass looked like this
public Object clone()
Then it would still be a valid cloneable object and it would work. You wouldn't need to cast anything. The interface, Cloneable is just a marker interface, which means it doesn't actually have any methods.
Your easy question first: why is super.clone() cast to MyClass? That's because the declaration of HerClass.clone() specified a returned value of HerClass, so you must cast it to the right type.
Now, for the more difficult question: how can super.clone() actually return an instance of MyClass? I actually had a hard time finding the answer, but I did somewhat find an answer in Effective Java by Joshua Bloch. There is still some "magic" in the background of Object.clone() that I don't quite understand.
Item 11 from the book:
In practice, programmers assume that if they extend a class and invoke
super.clone from the subclass, the returned object will be an instance
of the subclass. The only way a superclass can provide this
functionality is to return an object obtained by calling super.clone.
If a clone method returns an object created by a constructor, it will
have the wrong class. Therefore, if you override the clone method in a
nonfinal class, you should return an object obtained by invoking
super.clone. If all of a class’s superclasses obey this rule, then
invoking super.clone will eventually invoke Object’s clone method,
creating an instance of the right class.
I originally tried to answer your question by writing a program without knowing you always had to call super.clone(). My homemade clone method for HerClass was returning a new instance of HerClass generated from a constructor (new HerClass()). The code compiled, but it failed at execution when I was trying to cast (MyClass) super.clone(). Only methods that are chained down from Object.clone() can return a value that is an instance of one of their subtype.
Note that if HerClass.clone() is not explicitly implemented, by default it simply returns Object.clone(). The default method has protected access, but since you are calling it from a subclass, it's not a problem.

Why is the clone() method protected in java.lang.Object?

What is the specific reason that clone() is defined as protected in java.lang.Object?
The fact that clone is protected is extremely dubious - as is the fact that the clone method is not declared in the Cloneable interface.
It makes the method pretty useless for taking copies of data because you cannot say:
if(a instanceof Cloneable) {
copy = ((Cloneable) a).clone();
}
I think that the design of Cloneable is now largely regarded as a mistake (citation below). I would normally want to be able to make implementations of an interface Cloneable but not necessarily make the interface Cloneable (similar to the use of Serializable). This cannot be done without reflection:
ISomething i = ...
if (i instanceof Cloneable) {
//DAMN! I Need to know about ISomethingImpl! Unless...
copy = (ISomething) i.getClass().getMethod("clone").invoke(i);
}
Citation From Josh Bloch's Effective Java:
"The Cloneable interface was intended as a mixin interface for objects to advertise that they permit cloning. Unfortunately it fails to serve this purpose ... This is a highly atypical use of interfaces and not one to be emulated ... In order for implementing the interface to have any effect on a class, it and all of its superclasses must obey a fairly complex, unenforceable and largely undocumented protocol"
The Clonable interface is just a marker saying the class can support clone. The method is protected because you shouldn't call it on object, you can (and should) override it as public.
From Sun:
In class Object, the clone() method is declared protected. If all you do is implement Cloneable, only subclasses and members of the same package will be able to invoke clone() on the object. To enable any class in any package to access the clone() method, you'll have to override it and declare it public, as is done below. (When you override a method, you can make it less private, but not more private. Here, the protected clone() method in Object is being overridden as a public method.)
clone is protected because it is something that ought to be overridden so that it is specific to the current class. While it would be possible to create a public clone method that would clone any object at all this would not be as good as a method written specifically for the class that needs it.
The Clone method can't be directly used on any object, which is why it is intended to be overriden by the subclass.
Of course it could be public and just throw an appropriate exception when cloning is not possible, but i think that would be misleading.
The way clone is implemented right now makes you think about why you want to use clone, and how you want your object to be cloned.
IMHO it's as simple as this:
#clone must not be called on non-cloneable objects, therefore it is not made public
#clone has to be called by subclasses ob Object that implement Cloneable to get the shallow copy of the right class
What's the right scope for methods that shall be callable by subclasses, but not by other classes?
It's protected.
Classes implementing Cloneable of course will make this method public so it can be called from other classes.
It is protected because the default implementation does a shallow memberwise copy of all fields (including private), circumventing constructor. This is not something an object might be designed to handle in the first place (for example, it might keep track of created object instances in a shared list, or something similar).
For the same reason, the default implementation of clone() will throw if the object it's called on doesn't implement Cloneable. It's a potentially unsafe operation with far-reaching consequences, and therefore author of the class must explicitly opt-in.
From the javadoc of cloneable.
* By convention, classes that implement this interface (cloneable) should override
* <tt>Object.clone</tt> (which is protected) with a public method.
* See {#link java.lang.Object#clone()} for details on overriding this
* method.
* Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
* Therefore, it is not possible to clone an object merely by virtue of the
* fact that it implements this interface. Even if the clone method is invoked
* reflectively, there is no guarantee that it will succeed.
So you could call clone on every object but this would give you most of the time not the results you want or an exception. But is only encouraged if you implement cloneable.
Clone() method has a check internally 'instance of Cloneable or not'.This is how Java team might thought will restrict the improper use of clone() method.clone() method is protected i.e. accessed by subclasses only. Since object is the parent class of all sub classes, so Clone() method can be used by all classes infact if we don't have above check of 'instance of Cloneable'. This is the reason Java team might have thought to restrict the improper use of clone() by having the check in the clone() method 'is it instance of Cloneable'.
Hence whatever classes implement cloneable can use clone() method of Object class.
Also since it made protected, it is available to only those sub classes that implements cloneable interface. If we want to make it public, this method has to be overridden by the sub class with their own implementation of it.
Yes, same problem that I met.
But I solve it by implementing this code
public class Side implements Cloneable {
public Side clone() {
Side side = null;
try {
side = (Side) super.clone();
} catch (CloneNotSupportedException e) {
System.err.println(e);
}
return side;
}
}
Just as the before someone said.
Well, also the sun developers are only human, and they did indeed make huge mistake to implement the clone method as protected, the same mistake as they implemented a non-functioning clone method in ArrayList! So, in general, there exist a much deeper misunderstanding of even experienced Java programmers about the clone method.
However, I've recently found a fast and easy solution to copy any object with all its content, no matter how it is built and what it contains, see my answer here: Bug in using Object.clone()
Again, Java JDK framework shows brilliant thinking:
Cloneable interface does not contain a "public T clone();" method because it acts more like an attribute (eg. Serializable) which allows an instance it to be cloned.
There is nothing wrong with this design because:
Object.clone() will not do what you want with your custom-defined class.
If you have Myclass implements Cloneable => you overwrite clone() with
"public MyClass clone()"
If you have MyInterface extends Cloneable and some MyClasses implementing MyInterface:
simply define "public MyInterface clone();" in the interface and every method using MyInterface objects will be able to clone them, no matter their MyClass-class.

Categories

Resources