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()
?这对我来说听起来很合逻辑。
回答:
听起来这里至少有两个问题在起作用:
听起来您对clone()的正常实现方式感到困惑。
听起来您好像在想克隆是个好主意(与使用复制构造函数,工厂或其等效对象相比)。
这是克隆方法的实现示例:
@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