Java:super.clone()方法和继承

我有一个关于clone()Java中用于super.clone()继承的方法的快速问题-在哪里我clone()从按钮一直到父类中调用该方法。

clone()方法应该返回该对象的副本,但是如果我在继承继承中有三个类并调用super.clone()三次,为什么继承继承中的最高类(仅在Object类下)获取该类的副本回来?

假设我们有三个类:A,B和C,其中A-> B-> C(继承=->)

然后,super.clone()在类C中进行调用,clone()在B中进行调用super.clone(),在B中进行调用,clone()在A中进行调用,这将调用super.clone()“这次Object.clone()被调用”。为什么返回的不是this关于类A

的对象的副本Object.clone()?这对我来说听起来很合逻辑。

回答:

听起来这里至少有两个问题在起作用:

  1. 听起来您对clone()的正常实现方式感到困惑。

  2. 听起来您好像在想克隆是个好主意(与使用复制构造函数,工厂或其等效对象相比)。

这是克隆方法的实现示例:

@Override 

public Object clone() throws CloneNotSupportedException {

//get initial bit-by-bit copy, which handles all immutable fields

Fruit result = (Fruit)super.clone();

//mutable fields need to be made independent of this object, for reasons

//similar to those for defensive copies - to prevent unwanted access to

//this object's internal state

result.fBestBeforeDate = new Date( this.fBestBeforeDate.getTime() );

return result;

}

请注意,的结果将super.clone()立即转换为Fruit。这样,继承方法便可以修改特定于Fruit的成员数据(fBestBeforeDate在这种情况下)。

因此,对子clone()方法的调用虽然将调用父级的克隆,但也会对新制作的副本添加其自身的特定修改。在这种情况下,结果将是Fruit,而不是Object

现在,更重要的是, 。复制构造函数和工厂提供了更为直观和易于维护的替代方案。尝试阅读我附加到示例的Java

Practices链接上的标题:该标题总结了一些问题。乔什·布洛赫(Josh

Bloch)的讨论时间也更长:绝对应该避免克隆。这是一段很棒的摘要段落,说明了他为什么认为克隆是一个问题:

对象的克隆方法非常棘手。它基于字段副本,并且是“额外语言”。它创建一个对象而不调用构造函数。无法保证它保留了构造函数建立的不变式。多年来,在Sun内部和外部都有许多错误,这是由于以下事实造成的:如果您仅调用super.clone,直到在克隆对象之前,都在链中反复调用,则该对象会有一个浅表副本。克隆通常与要克隆的对象共享状态。如果该状态是可变的,则您没有两个独立的对象。如果您修改其中一个,则其他也将更改。突然之间,您会得到随机的行为。

以上是 Java:super.clone()方法和继承 的全部内容, 来源链接: utcz.com/qa/417458.html

回到顶部