听起来这里至少有两个问题在起作用:
听起来您对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,直到在克隆对象之前,都在链中反复调用,则该对象会有一个浅表副本。克隆通常与要克隆的对象共享状态。如果该状态是可变的,则您没有两个独立的对象。如果您修改其中一个,则其他也将更改。突然之间,您会得到随机的行为。



