简体   繁体   中英

Why when implementing clone method we return super.clone() not this clone()

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.

The superclass clone method should be Object.clone() or it should delegate 1 (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.

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:

  • increasing the visibility to public (if you want that)
  • copying any mutable objects referenced from the class that were not copied by 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.

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:

  • make clone() public ( Object.clone() is protected)
  • handle cases where a subclass doesn't implement Cloneable gracefully by printing the stacktrace and returning null .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM