Java:clone() 操作调用 super.clone()

Posted

技术标签:

【中文标题】Java:clone() 操作调用 super.clone()【英文标题】:Java : clone() operation calling super.clone() 【发布时间】:2011-07-22 19:17:02 【问题描述】:

我不完全理解在类的 clone() 方法中返回 super.clone() 的想法。首先,这是否与它返回一个包含比请求的数据少的超类的对象有关,因为超类“不是”子类,而是子类“是”超类。如果有一个很长的子类链,每个都调用 super.clone(),那为什么不会导致它最终在链的根部调用 Object.clone(),这不是任何子类?

对不起,如果这令人困惑;我有时会迷惑自己

【问题讨论】:

***.com/questions/2156120/… 这是有人问的最令人困惑的问题,但答案已尽可能简化.. 【参考方案1】:

仔细阅读javadoc of Object.clone():它返回对象的副本。副本是与调用克隆的对象相同的类的另一个实例。 IE。 foo.clone().getClass() == foo.getClass().

【讨论】:

问题的关联在哪里?【参考方案2】:

Object 中的clone() 实现检查实际类是否实现Cloneable,并创建该实际类的实例。

所以如果你想让你的类可克隆,你必须实现Cloneabledowncast super.clone() 的结果到你的类。另一个负担是对super.clone() 的调用可能会抛出一个你必须捕获的CloneNotSupportedException,即使你知道它不会发生(因为你的类实现了Cloneable)。

Cloneable 接口和clone 类上的clone 方法是面向对象设计出错的明显案例。

【讨论】:

我一直在读到我应该避免使用 clone(),但我至少想了解它是如何工作的......这让我发疯了 @TurtleToes:如果所有祖先类都使用 Super.Clone 实现克隆,那么派生类应该使用使用 super.clone 的版本覆盖克隆,或者简单地让派生类继承现有的克隆方法。如果任何祖先类使用复制构造函数来实现它,那么所有派生类也必须使用复制构造函数;在这种情况下,使用继承的克隆方法将不是一个选项。 '(...) 并创建该实际类的实例'。在不调用构造函数的情况下说Object#clone() 中的规范;我猜这涉及到魔法。 为什么这是公认的答案?它没有解释任何理由。它只是重复你必须做的事情,而不是重复的原因。我认为 Cloneable 是 100% 废话,只需编写一个 copy() 方法来复制我的对象...【参考方案3】:

考虑一下:你有一个继承类链。每个可能(或可能没有)有自己的变量。与复制引用的等号运算符 (==) 不同,clone 的作用是复制具有新引用的对象的副本。 对于上面的示例,您想克隆链中的最后一个对象。 由于最后一个对象是由其超类构成的,每个超类都可能有不同的克隆方法实现,因此在克隆自己的对象之前调用 clone 的超类实现以首先接收克隆的父对象是很有意义的。

通常与克隆相关的另一个术语是浅层克隆和深层克隆。 浅克隆是指创建对象的精确副本,而深度克隆创建对象的副本以及原始对象所引用的任何子对象。

更多关于克隆的信息请访问this link

【讨论】:

如果我有一个实现 Cloneable 的类,并且它有具有 clone() 函数的子类,这些子类也不需要实现 Cloneable 吗?那是因为接口是从超类派生的吗?另外,子类不需要尝试异常,我假设是因为超类已经在尝试并且没有抛出异常?对吗? 如果一个超类实现了cloneable,那么它的所有子类也会自动实现cloneable,不需要显式指定这个实现。至于您的第二个问题,不确定我是否理解措辞:“尝试例外”。你能澄清一下吗? 在object的直接子类中,你必须实现一个try块来捕获Object.clone()抛出的异常。它不会让你不检查它。但是,这个子类的子类在调用 super.clone() 时不需要像超类那样检查异常。 这是不正确的。无论您在继承树中的位置如何,只要调用 super.clone() 就需要异常处理。例如你有 3 个类:UpperMostClass 实现 Cloneable,ParentClass 扩展 UpperMostClass,ChildClass 扩展 ParentClass。由于它们都是可克隆的,因此对 super.clone() 的每次调用都需要处理,因为 CloneNotSupportedException 是一个检查异常。对你有感觉吗?

以上是关于Java:clone() 操作调用 super.clone()的主要内容,如果未能解决你的问题,请参考以下文章

Java的clone()方法

详解Java中的clone方法

Object在其子类中,为啥不能调用clone()???

关于clone(java.lang.Object)重写

java 浅拷贝和深拷贝

高效Java:clone()方法分析