What is the point in letting my class implement Cloneable?
Asked Answered
J

3

27

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?

Jobless answered 12/5, 2013 at 13:6 Comment(1)
You have your class implement Cloneable so that you can use the built-in cloning mechanisms, so other classes can clone yours without having to know it's unique clone methods. Yes, it is a bit of a strange way to manage it, but partly it has to do with backwards compatibility.Counterfoil
V
38

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().

Vizard answered 12/5, 2013 at 13:10 Comment(4)
Well as I can understand from your answer, today this is not recommended to use this interface, and it's only use is: if I want to use the clone method of Object class then I should implement it. In my case (the class where I saw this implementation) a more deeper copy of the class was implemented, So in this case is the any reason to implement this interface?Jobless
If you want to override and use the Object.clone() method, you need to implement this interface. If you want to perform a copy in another way, then just do whatever you want.Vizard
Got ya, so overriding the Object.clone() forces me to use this interface. Thanks for your informative answer.Jobless
> Usually, you should prefer using a copy constructor instead of using clone(). The problem with copy constructor, as I just discovered lastly, is that they are a bad choice when you have to duplicate objects for which you only know the interface type. For example if you have an object A containing a List<Thing> where Thing is an interface then you are screwed because you don’t know the exact type of Thing that are laying inside the List thus you cannot use copy constructor in this case to clone the objects in the list.Loveland
D
2

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.

Danforth answered 12/5, 2013 at 13:13 Comment(0)
B
0

In addition to what others said, Cloneable is often used when implementing prototype design pattern.

Breakout answered 26/5, 2019 at 4:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.