复制和克隆有什么区别?

32

在编程中是否有权威参考资料?

我看到很多人把深拷贝和克隆视为同一件事。这是真的吗?

它是否与语言有关?

虽然这只是一个小细节,但它一直在困扰着我...


3
我不相信有任何明确的一致意见来说明它们的相对含义。 - Mitch Wheat
5个回答

34

这些概念没有正式的定义,至少没有一个适用于所有语言的定义。

通常情况下:

  • clone - 基于已经存在的内容创建出全新的内容。
  • copying - 从已经存在的内容中复制到另外一个已经存在的地方。

13

是的,有所不同。就语言依赖性而言,一些语言可以执行所有浅层、深层、惰性复制。有些只能进行浅层复制。因此,有时确实取决于语言。

现在,以数组为例:

int [] numbers = { 2, 3, 4, 5};
int [] numbersCopy = numbers;

“numbersCopy” 数组现在包含相同的值,但更重要的是数组对象本身指向与“numbers”数组相同的对象引用。

因此,如果我要做类似以下的事情:

  numbersCopy[2] = 0;
 

以下语句的输出结果将会是什么?
  System.out.println(numbers[2]);

  System.out.println(numbersCopy[2]);

考虑到两个数组指向同一引用,我们将得到:

0

0

但是如果我们想要创建一个具有自己引用的第一个数组的独立副本呢?在这种情况下,我们需要克隆数组。通过这样做,每个数组将拥有自己的对象引用。让我们看看这将如何工作。
  int [] numbers = { 2, 3, 4, 5};

  int [] numbersClone = (int[])numbers.clone();

“numbersClone” 数组现在包含相同的值,但是在这种情况下,数组对象本身指向的引用与 “numbers” 数组不同。

因此,如果我要做类似以下的操作:

  numbersClone[2] = 0;

现在对于以下语句,输出会是什么?
  System.out.println(numbers[2]);

  System.out.println(numbersClone[2]);

你猜对了:

4

0

源代码


7
你的第一个例子(numbersCopy)既不是副本也不是克隆,而是一个引用。 - cowlinator

7

最简洁的概述:

  • copy: 复制到现有实例(浅复制或深复制)
  • clone: 复制到新实例(始终为深复制)

开发人员通常松散地交替使用它们,因此没有共识;但是您可以基于以下理由提出上述观点:

  1. 词源学(生物学)暗示“浅克隆”的概念是荒谬的,因为并不具有基因相同性;克隆意味着完整性以传播实体。
  2. 历史上,“复制”意味着将副本复制到现有介质上(复制书籍或绘画等)。例如,影印件将图像复制到现有纸张上。如果能够克隆一张纸,结果将是一张新纸。
  3. 可以“复制”对象引用,但永远不会“克隆”对象引用。

3

我认为“复制”和“克隆”是类似的术语。你需要注意的是,你可以获得浅复制和深复制。浅复制仅复制一个对象的根级别,而深复制会产生一个对象及其所有子对象的副本。


我同意。我认为在开发人员中,这些术语通常是可以互换使用的,至少在我参与的项目中是如此。最好总是说明深度,即浅复制/克隆深度复制/克隆 - Dan Stevens

2
在C++领域中,“克隆”通常是多态类对象进行深拷贝的习惯用语。
在Java/C#中,我怀疑这些术语更容易互换使用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接