Reputation: 63
public abstract class Shape implements Cloneable {
private String id;
protected String type;
abstract void draw();
public String getType(){
return type;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
Suppose i want to get a clone of an object then why we always return super.clone()
.if i want to clone an object then i suppose this is the object i want to clone.I am a beginner at cloning.
Upvotes: 4
Views: 3336
Reputation: 718768
The superclass clone
method should be Object.clone()
or it should delegate1 (ultimately) to Object.clone()
. That is a "magic" method that knows how to create a new instance of the actual class of the current instance.
And, of course, if you were to try to implement clone like this:
public Object clone() {
return clone();
}
you would create a recursion loop that would quickly end with a StackOverflowError
.
1 - If super.clone()
does not ultimately delegate to Object.clone()
, then it won't be able to clone the value of the fields defined by Shape
and its concrete subtypes.
Note that this particular example, the clone()
could be simplified to this:
public Object clone() {
return super.clone();
}
The Shape
class has Object
as its superclass, and the only case where Object.clone()
will throw CloneNotSupportedException
is if the actual class did not implement
the Cloneable
interface. But Shape
does that itself.
In fact. all this declaration of clone()
is really doing is to increase the visibility of the protected
version of clone()
in the Object
API.
Upvotes: 4
Reputation: 82461
The object that is dereferenced is the same, whether you use super
or this
. However, since you're overriding the clone
method using this.clone()
would lead to (infinite) recursion. Using super.clone()
you make sure to call the clone
implementation of the superclass.
Note that Object.clone
copies the whole object, regardless of the actual type.
The only thing that you need to take care of when overriding the method is:
public
(if you want that)super.clone()
The following example shows the usual way of cloning a object
public class Sheep implements Cloneable {
private String name;
public Sheep(String name) {
this.name = name;
}
public static void main(String[] args) throws CloneNotSupportedException {
Sheep s = new Sheep("dolly");
Sheep s2 = (Sheep) s.clone();
s2.numbers[0] = 42;
System.out.println(s);
System.out.println(s2);
}
private int[] numbers = new int[1];
@Override
public Object clone() throws CloneNotSupportedException {
Sheep clone = (Sheep) super.clone();
// copy referenced mutable objects
clone.numbers = this.numbers.clone();
// no need to copy name, since String is immutable
return clone;
}
@Override
public String toString() {
return "Sheep{" + "name=" + name + ", numbers=" + Arrays.toString(numbers) + '}';
}
}
Note that commenting out the line
clone.numbers = this.numbers.clone();
will lead to the arrays being the same.
Upvotes: 1
Reputation: 88707
In your example super.clone()
refers to Object.clone()
whose JavaDoc states:
Otherwise, 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.
That means that if a shallow copy is sufficient then using super.clone()
is sufficient. The override serves 2 purposes here:
clone()
public (Object.clone()
is protected)Cloneable
gracefully by printing the stacktrace and returning null
.Upvotes: 1