5
public class Color {
 String color;
 Color(String color)
 {
   this.color=color;         
 }
 }


public class ColoredCircle {
int x;
Color color;
ColoredCircle(int x, Color color)
{
    this.x=x;
    this.color=color;
}
public Object testClone()
{
    Color c = new Color(this.color.color);
    ColoredCircle cc1 = new ColoredCircle(this.x, c);
    return cc1;
}
}

In the class ColoredCircle mentioned above we have a method named testClone() and it works exactly as Deep Cloning. Now I am confused about the fact that is it necessary to implement Cloneable to clone? And Is the above program a kind of Deep cloning?

Arijit Dasgupta
  • 325
  • 3
  • 14
  • In fact, it is considered very bad to use `Cloneable` and implement `clone` these days. – RealSkeptic Oct 14 '15 at 13:49
  • Because shallow copy requires less memory than deep one. – John Oct 14 '15 at 13:51
  • @RealSkeptic so I hope it is not necessary to implement Cloneable to deep clone? – Arijit Dasgupta Oct 14 '15 at 13:59
  • you may programmatically clone Objects but what about arrays? – Kumar Abhinav Oct 14 '15 at 14:01
  • 1
    @ArijitDasgupta I don't get your last question to RealSkeptic. You can implement deep copy in a method called `sljgfsaja`. This will do the job but not implement the interface `Clonable`. Your clients just have to know they have to use that method. There is no international Java law enformcement tag team kicking in your door if don't use the interface ... Maybe I just misunderstood the question. – Fildor Oct 14 '15 at 14:05
  • @Fildor Thanks for the explanation. The explanation and the humour gave me some sort of relief !!! – Arijit Dasgupta Oct 14 '15 at 14:31
  • Important to know: [Aboout java cloneable](http://stackoverflow.com/q/4081858/4125191). – RealSkeptic Oct 14 '15 at 17:19
  • @RealSkeptic when I am deep cloning, I normally do not use the .clone() method. I manually implement the logic. Because of this it does not throw CloneNotSupportedException as I don't implement the Cloneable interface. So my question is, Is it really needed to implement the interface when it has no work technicaly – Arijit Dasgupta Oct 14 '15 at 19:50
  • 1
    It doesn't matter if you are deep or shallow cloning. If you are not using `clone`, you are not supposed to implement `Cloneable`. And since it is discouraged to implement `Cloneable` and `clone` at all, you are supposed to do your deep copying by other means. – RealSkeptic Oct 14 '15 at 19:53

3 Answers3

3

Implementing the Cloneable interface is needed in order for a call to Object.clone() to not throw an exception. (That's the entire purpose of Cloneable.)

You are not using Object.clone(). So implementing Cloneable or not has no effect. It has nothing to do with what your method is called. Your method could be called testClone() and it can call up to super.clone(). Or your method could be called clone() and it could not use super.clone(). What matters is you are not using Object.clone().

The advantage of using Object.clone() is that the object it returns has the same exact runtime class as the object it is called on. On the other hand, your method creates a new ColoredCircle object always. So when your testClone() method is inherited in a subclass, it will still create a ColoredCircle, and not an instance of that subclass. Whereas if your method called super.clone() it will be able to get an instance of whatever subclass the current instance is.

newacct
  • 119,665
  • 29
  • 163
  • 224
1

Is it necessary to implement Cloneable to clone? Yes.The clone() method is having protected access modifier with the following Javadoc explantion :-

This method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a shallow copy of this object, not a deep copy operation.

Your method testClone although may be correct in cloning behavior but is not a Cloneable Object in itself.A Cloneable object must implement Cloneable interface and preferably have a public access for clone() so that it can be used outside the class.

Someone reaading your class will have a hard time understanding the importance of testClone() method.

Kumar Abhinav
  • 6,565
  • 2
  • 24
  • 35
  • 1
    Depends on what you mean by "clone". Is it necessary to implement `Cloneable` to use the `clone()` method according to its contract? Yes. Is it necessary in order to generally clone (make a copy of) an object? No. A copy constructor or something similar is much more preferable. – RealSkeptic Oct 14 '15 at 14:10
0

Cloneable is a marker interface. It contains no methods.

The thing is that the clone method is defined in the Object class. Since all classes implement the Object class, that means that all classes have a clone method. However, not all objects actually support it. Some of them will just throw a CloneNotSupportedException. But this clone method is a native method, and therefor the exact behavior of this method is not visible in the java source code. So, it lacks some transparency.

The Cloneable interface is there to help us recognize which classes are really cloneable and which are not. By convention, classes that don't implement Cloneable will throw the CloneNotSupportedException.

Note: the clone method is also marked protected. So, it's also convention to override it to make it public in supporting classes.


The clone design was introduced in JDK1. These days the general concensus is that the java clone design contains some flaws. Some prefer to just create a cloning constructor (e.g. public Color(Color toCopy) {this.color = toCopy.color;})

bvdb
  • 22,839
  • 10
  • 110
  • 123
  • "that means that all classes have a clone method." But most classes do not have a *public* `clone` method. – newacct Oct 17 '15 at 08:54
  • @newacct indeed, your point being ? - I mean, I mentioned it in my answer, didn't I ? – bvdb Oct 17 '15 at 19:58
  • Other than to the class itself or its subclass, the only "methods" a class has are public methods. So the statement is useless, because for all effects and purposes, to regular code, most objects do not have an accessible method called `clone`. You furthermore say "However, not all objects actually support it." which again contrasts "not all" with "all", which again implies that they all "have it". But not only do some objects "not support it", most objects don't even "have it" at all from the perspective of code outside that class. – newacct Oct 18 '15 at 08:15
  • @newacct it is always accessible, even if it's not `public`. It's accessible to child classes and classes within the same package. (not even to mention reflection which is very relevant in the age of proxy objects and aop which play an increasing big role in java.) – bvdb Oct 18 '15 at 09:03
  • @newacct secondly, the "not all" is indeed there to make a contrast. While **all** objects have it, **most of them** will throw the `CloneNotSupportedException`, which bubbles up all the way from the native level code. – bvdb Oct 18 '15 at 09:06
  • @newacct in comments on your last statement: I couldn't disagree more. All objects really have the `clone` method. That's just a fact. And I guess I can agree that it's a method without a body **on java level**, but that's the case for all native methods. The body is just there **on C++ level**. – bvdb Oct 18 '15 at 09:17