Java中克隆的目的

Purpose of cloning in Java

本文关键字:Java      更新时间:2023-10-16

我正在学习Java的"特殊"功能,并开始阅读克隆。

所以目前我所了解的是,克隆可以用来获得一个对象的相同副本。要做到这一点,你需要实现可克隆接口并覆盖Object的克隆方法(这真的很奇怪IMO)

我的问题更多的是针对C++和Java之间的比较。当我们已经支持复制构造函数时,为什么需要一个单独的克隆方法呢。为什么克隆被认为必须具有特征,这有历史原因吗?

附言:我不是在问"克隆"的必要性,因为在Java中克隆对象的必要性是什么,我问的是在Java已经支持复制构造函数的情况下,需要克隆和克隆方法。

您所问的IMO有两部分。

Cloneable接口需要什么?

可克隆接口也称为标记接口,这意味着它没有任何方法,它的全部目的是告诉该类的用户,它实现了从Object继承的克隆()方法。这使您能够在调用clone()方法之前进行检查:

Animal a = new Dog();
Animal b;
if (a instanceof Cloneable)
    b = a.clone();

这种情况在Java中经常发生;例如,请参阅Serializable接口。

为什么Java需要一个clone()方法,因为它已经有了复制构造函数?

简短的答案是多态性。如果没有clone()方法,如何通过引用其超类Animal来正确克隆Dog实例?

克隆旨在提供一个单独的对象实例,而不破坏克隆的实例。它在原型模式中非常有用(这是必须的)。

复制构造函数通常在C++中传递值时调用(您也可以在构造时使用它,但通常在将对象作为参数或返回通过堆栈时调用它)。初始对象经常超出范围。

如果你真的想这样做的话,你最终可以交换这两种,但事实上,它们有不同的用途,明确何时应该使用其中一种而不是另一种是非常有帮助的。

除了消除名称的歧义之外,还需要考虑多态性,即从基指针克隆对象。

复制构造函数将在指针类型上调用,而克隆(如果是虚拟的,就像它应该是虚拟的)将在派生程度最高的实现上调用。