I came across some class code that implements Clonable, the documentation states:
A class implements the Cloneable interface to indicate to the Object.clone() method that it is legal for that method to make a field-for-field copy of instances of that class.
Invoking Object's clone method on an instance that does not implement the Cloneable interface results in the exception CloneNotSupportedException being thrown.
By convention, classes that implement this interface should override Object.clone (which is protected) with a public method. See Object.clone() for details on overriding this method.
Note that this interface does not contain the clone 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.
I can't understand the point in implementing this class, as said in the docs the .clone method is not implemented in the interface, and I have to implement it. So why use this class? Why won't I just write a method copyClass in my class to make the object copy without the implementation of this class?
To implement the clone method, you simply do:
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
You can of course customize the method to make a deeper copy if needed.
Calling super.clone() is almost mandatory because, unless the class is final and thus can't be overridden, the clone() method must return an instance of the same class as the object on which it's called. So simply creating a new instance and copy the state will work for this class, but not for all the subclasses. Moreover, you don't always have access to all the state contained in superclasses.
In short, you make the protected clone method of Object public. And the first thing that the Object.clone() method does is (this is not the real code, but this is what the method does):
if (!(this instanceof Cloneable)) {
throw new CloneNotSupportedException();
}
So, Cloneable is just a marker interface to let the Object.clone() method know that it must not throw an exception when called.
This is one of the most badly-designed parts of Java. Usually, you should prefer using a copy contructor instead of using clone().
It allows you to write more generic code. If you have multiple classes implementing Cloneable interface, and want to pass their instances as an argument to method, you don't have to create multiple methods differing with one variable type, you can just use Cloneable t. It's the same with other interfaces. And, the same with every other interface, it's kinda multiple inheritance. Implementing those interfaces makes your code more legible too.
In addition to what others said, Cloneable is often used when implementing prototype design pattern.
Related
I am in the process of migrating to java from c++ and consider myself a java noob. I have been looking recently at a vast code base with several examples of the kind public class Myclass implements Cloneable{...} with no implementation of the clone function. I fail to understand the advantages of this pattern. Are there any? If you choose not to implement the clone function, why derive it from Cloneable? Also are there any lombok anotations which provide some default clone functions?
If a class does not implement the Cloneable interface, calling clone on an instance of the class results in a CloneNotSupportedException. The java.lang.Object already implements a clone method (this method is not abstract), so subclasses are not required to implement it. The clone method of java.lang.Object performs a shallow copy of the instance.
If you choose not to implement the clone function, why derive it from
Cloneable?
The clone() method doesn't derive from the Cloneable interface. It comes from the Object class.
Cloneable is simply a marker interface. It is used at runtime to valid the behavior if the clone() method is called on a instance of a class.
Java has chosen a design model where by default the object owns the clone() method. It is a design choice you may like or not but anyway, it is like that
Concretely, if you call clone() on a object and the class of the object doesn't implement Clonable, the JVM will at runtime throw a CloneNotSupportedException exception. In a same way, some classes throw UnsupportedOperationException if one of their method is not implemented.
Also are there any lombok anotations which provide some default clone
functions?
By default, clone() performs a shallow copy of the current object. That is, a new instance is created for the object you are cloning but all object fields that it owns are not cloned. Indeed, the fields of the cloned object still reference the same objects than those in the original instance. Only fields with primitive types (int, float, boolean, etc...) are cloned.
If you need to have a different behavior in the clone() method, Lombok cannot guess what is the behavior you want to have. So, no it makes no sense to use it to generate the implementation of the clone() method.
There is actually a #Wither annotation in lombok:
https://projectlombok.org/features/experimental/Wither.html
But you could also just create a new object passing parameters to a constructor.
What is the point of the cloneable interface in Java? The core object in java has a clone() method. Could you not just override that method?:
#Override
public Foo clone(){
return new Foo(this.x, this.y);
}
Please explain why the you would use the interface. I already know the ins and outs of cloning an object. I just don't get why you would use the interface.
To answer your first question, you must implement the Clonable interface for the clone() method to work since Object's clone checks that the interface is implemented otherwise it will throw an exception.
Using clone() is a bad idea. It was one of the original ideas in Java that didn't work out. There are some design issues including it usually being a shallow copy. If you want to make a copy or a deep copy of an object, it's best to create a copy constructor or a copy method to do it without using clone. Using clone() correctly is hard.
If really you want to use the clone(), then read this blog post which explains how to use clone(). Basically there are 5 points to remember when using clone():
1) Clone method is used to create a copy of object in Java. In order to use clone() method, class must implement java.lang.Cloneable interface and override protected clone() method from java.lang.Object. A call to clone() method will result in CloneNotSupportedException, if that class doesn't implement Cloneable interface.
2) No constructor is called during cloning of Object in Java.
3) Default implementation of clone() method in Java provides "shallow copy" of object, because it creates copy of Object by creating new instance and then copying content by assignment, which means if your Class contains a mutable field, then both original object and clone will refer to same internal object. This can be dangerous, because any change made on that mutable field will reflect in both original and copy object. In order to avoid this, override clone() method to provide deep copy of object.
4) By convention, clone of an instance should be obtained by calling super.clone() method, this will help to preserve invariant of object created by clone() method i.e. clone != original and clone.getClass() == original.getClass(). Though these are not absolute requirement as mentioned in Javadoc.
5) Shallow copy of an instance is fine, until it only contains primitives and Immutable objects, otherwise, you need to modify one or more mutable fields of object returned by super.clone, before returning it to caller.
As mentioned in the Java Docs:
A class implements the Cloneable interface to indicate
to the Object.clone() method that it is legal for that method
to make a field-for-field copy of instances of that class.
Specifically:
Invoking Object's clone method on an instance that does not
implement the Cloneable interface results in the exception
CloneNotSupportedException being thrown.
Please let me know if you have any questions.
For example, we write the class XXX to implement the Cloneable, and we override the method clone in the class XXX, is it necessary to invoke super.clone in the method?
A couple of important pointers
Cloneable is a marker interface. Marker interface does not have methods or variables declared. They just tell the JVM that this class has a capability of doing something for example cloneable, serializable etc
When you are saying super.clone, you are not invoking a method from cloneable, you are actually invoking clone() method of super class or by default Object.clone();
If you do not want an implementation of your own, you can use Object's clone method, but that will give you a shallow copy of your object. If you want to do something more than that, it is better to give your own implementation.
And regarding your original question, no it is not a compulsion to call a super method if you know your code is handling everything. But if you need to use functionality from a super class (in this case Object class), you should call super method
Yes. If you don't call the super class implementation, any data it needs won't be copied to the new clone.
UPDATE
For example, super class may want to copy it's private variables to the new clone.
Actual implementation should be
XXX clone = super.clone();
// 'clone' now has all the data the super class wants to know.
// add any details from your XXX class to it here.
return clone;
If we override the method clone in the class XXX - NO call to super is needed. You just do there what you want. - means copy what and how you like it to be copied.
*edit
ok i was wrong
here is what super.clone() calls:
http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#clone%28%29
you should call super.clone()
The Java specification for the java.lang.Cloneable interface defines itself as signifying that any object that extends it also has implemented the clone() method that rests dormant within java.lang.Object. Specifically, it says that:
A class implements the Cloneable interface to indicate to the java.lang.Object#clone() method that it is legal for that method to make a field-for-field copy of instances of that class.
To me, this means that it should be assumed that every class that extends Cloneable therefore also has a public Object clone() method within it. This makes it easy to assume that the following is a valid method:
public static makeACloneFrom(Cloneable c)
{
return c.clone();
}
however, this is not the case, as the entirety of the Cloneable source code (sans javadoc) is simply
package java.lang;
public interface Cloneable {
}
Which means that Cloneable#clone() does not exist (and trying to compile the example method above throws a compile-time error saying something like "cannot find symbol: method clone()"). Shouldn't the source code of Cloneable contain something to the effect of public Cloneable clone();?
Why aren't we allowed to assume that a class that implements Cloneable has a public Cloneable clone() method?
Because it's a poorly-designed interface.
From Effective Java (sorry, Google Books does not have a preview for the 2nd edition):
Item 11: Override clone judiciously
The Cloneable interface was intended as a mixin interface (Item
18) 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, with resorting to reflection (Item 53), invoke the clone
method on an object merely because it implements Cloneable. Even a
reflective invocation may fail, as there is no guarantee that the
object has an accessible clone method.
Ugh. clone and Cloneable are broken, terribly designed, and shouldn't be used in new code. (See Effective Java item 11.)
The reason for this particular thing is that Cloneable is a confusingly implemented, magical interface such that the mere act of implementing Cloneable changes the behavior of Object.clone with reflection. Effective Java says:
...if a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException. This is a highly atypical use of interfaces and not one to be emulated...
If I have:
class foo implements Cloneable
and then do:
bar = new foo();
bar.clone();
I get a shallow copy without needing to write any bar.clone() code like I normally would need to do when I implement an interface.
My understanding is that an interface's functions must be filled in by the class implementing it, and Object.clone() has no implementation (as per the docs, "The class Object does not itself implement the interface Cloneable")
So where does my shallow clone come from? Where is the code that implements bar.clone() if Object.clone() has no implementation? I'm confused.
Be very careful using clone. In fact, I would avoid it completely. I have never needed it. BUT... that being said, the best discussion of the topic I have ever read is by Joshua Bloch, in Effective Java. Read Item 11: "Override clone judiciously".
PLEASE do yourself a favor and read that item. I actually recommend reading that entire chapter (and the rest of the book). Everything you need to know about clone and why I caution you about it is in there.
Hope this helps.
Object.clone() has an implementation:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Object.html#clone()
This link explains the Cloneable interface:
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Cloneable.html
An object must implement the Cloneable interface in order to call the clone() method, otherwise, it throws a CloneNotSupportedException.
By definition, all classes in Java extend the base Object class, and Object class has a default clone() method, even though Object itself does not implement Cloneable. The Object class's clone() method will be called if you do not override it yourself.
If I have: "class foo implements
cloneable"
and then do: bar = new foo();
bar.clone();
I get a shallow copy without needing
to write any bar.clone() code like I
normally would need to do when I
implement an interface.
That would only work if you are calling it within the class "foo", because the .clone() method inherited from Object is protected.
My understanding is that an
interface's functions must be filled
in by the class implementing it, and
Object.clone() has no implementation
(as per the docs, "The class Object
does not itself implement the
interface Cloneable")
(1) Object.clone() does have an implementation. It makes a shallow copy of the object if the object implements Cloneable. (2) The .clone() method is not part of any interface. (3) Having a .clone() method and implementing the Cloneable interface are completely separate things. You only need to implement the Cloneable interface if you intend to make use of Object's clone method; however, this is the recommended way to write a clone method for your class -- to get its copy from the superclass's clone method, which eventually goes up to Object's clone method.
My understanding is that an interface's functions must be filled in by the class implementing it, and Object.clone() has no implementation (as per the docs, "The class Object does not itself implement the interface Cloneable")
there is a difference between saying Object.clone() has no implementation
and The class Object does not itself implement the interface Cloneable
Object's clone method does have implementation, it does memory-copy of the object who called clone method.
you are right, Object class does not implement cloneable, all it does is check the object is cloneable or not .
the above answer point's you to read some book, i think i can give a quick solution
so to answer your question
So where does my shallow clone come from?
Object's clone method
Where is the code that implements bar.clone() if Object.clone() has no implementation?
it has implementation, written in native code.