Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么在实现clone方法时返回super.clone()而不是this clone()_Java - Fatal编程技术网

Java 为什么在实现clone方法时返回super.clone()而不是this clone()

Java 为什么在实现clone方法时返回super.clone()而不是this clone(),java,Java,假设我想克隆一个对象,那么为什么我们总是返回super.clone()。如果我想克隆一个对象,那么我想这就是我想克隆的对象。我是克隆的初学者。超类clone方法应该是object.clone(),或者它应该(最终)将1委托给object.clone()。这是一个“神奇”的方法,它知道如何创建当前实例的实际类的新实例 当然,如果您尝试像这样实现克隆: public abstract class Shape implements Cloneable { private String id;

假设我想克隆一个对象,那么为什么我们总是返回
super.clone()
。如果我想克隆一个对象,那么我想这就是我想克隆的对象。我是克隆的初学者。

超类
clone
方法应该是
object.clone()
,或者它应该(最终)将1委托给
object.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;
   }
}
您将创建一个递归循环,该循环将以
stackoverflowerrror
快速结束


1-如果
super.clone()
最终没有委托给
Object.clone()
,则它将无法克隆由
Shape
及其具体子类型定义的字段值


请注意,在这个特定示例中,
clone()
可以简化为:

public Object clone() {
    return clone();
}
Shape
类将
Object
作为其超类,
Object.clone()
将抛出
CloneNotSupportedException
的唯一情况是,如果实际类没有
实现
Cloneable
接口。但是
Shape
本身会这样做


事实上,
clone()
的所有声明实际上是为了增加
受保护的
版本的可见性
对象中的
对象
API。

无论您使用的是
super
还是
this
,被解除引用的对象都是相同的。但是,由于您使用
this.clone()
覆盖
clone
方法,因此会导致(无限)递归。使用
super.clone()
确保调用超类的
克隆
实现

请注意,
Object.clone
复制整个对象,而不考虑实际类型

重写该方法时需要注意的唯一事项是:

  • 增加对
    公共
    的可见性(如果需要)
  • 复制未被
    super.clone()

下面的示例显示了克隆对象的常用方法

public Object clone() {
    return super.clone();
}
请注意,注释掉该行

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) + '}';
    }

}

将导致数组相同。

在您的示例中
super.clone()
指的是
Object.clone()
,其JavaDoc状态为:

否则,此方法将创建此对象类的新实例,并使用此对象对应字段的内容初始化其所有字段,就像通过赋值一样;字段的内容本身不会被克隆。因此,此方法将执行此对象的“浅拷贝”而不是“深拷贝”操作

这意味着,如果浅拷贝就足够了,那么使用
super.clone()
就足够了。覆盖在这里有两个用途:

  • clone()
    公开(
    Object.clone()
    受保护)
  • 通过打印stacktrace并返回
    null
    ,处理子类不能优雅地实现
    Cloneable
    的情况

您可以通过适当的示例找到解释。
这个.clone()
是简单的递归。您将得到一个
堆栈溢出错误
超级.clone();
与构造函数中的
超级()
非常相似。克隆方法必须链接。
对象.clone()
很神奇,但是在此上下文中,
super
可能不是
对象
是的。你是对的。(我正在更正…)但是,如果
super.clone()
没有委托给
Object.clone())
此实现不起作用!@AndrewTobilko-在本例中,我们知道
Shape
的超类型是
Object
。请查看它是如何声明的。
clone.numbers = this.numbers.clone();