我有一个关于Java中clone()方法的快速问题,在继承方面用作super.clone() – 我在父类中从按钮一直调用clone()方法.
clone()方法应该返回这个对象的副本,但是如果我在继承heirachy中有三个类并且调用super.clone()三次,为什么不继承heirachy中的最高类,就在类下面对象,获取该类返回的副本?
假设我们有三个类:A,B和C,其中A – > B – > C(继承= – >)
然后在类C中调用super.clone(),调用B中的clone()调用super.clone(),在A中调用clone()调用super.clone()’这次调用Object.clone()’.为什么它不是从Object.clone()返回的类A的this对象的副本?这听起来很合乎逻辑.
解决方法:
听起来这里至少有两个问题在起作用:
>听起来你对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()方法虽然它将调用父类的克隆,但也会对新制作的副本添加自己的特定修改.在这种情况下,出来的将是一个水果,而不是一个对象.
现在,更重要的是,克隆是一个坏主意.复制构造函数和工厂提供了更直观,易于维护的替代方案.尝试阅读我附加到示例的Java Practices链接上的标题:总结了一些问题. Josh Bloch也有a much longer discussion:绝对应该避免克隆.以下是关于他认为克隆是一个问题的原因的优秀摘要段落:
Object’s clone method is very tricky. It’s based on field copies, and
it’s “extra-linguistic.” It creates an object without calling a
constructor. There are no guarantees that it preserves the invariants
established by the constructors. There have been lots of bugs over the
years, both in and outside Sun, stemming from the fact that if you
just call super.clone repeatedly up the chain until you have cloned an
object, you have a shallow copy of the object. The clone generally
shares state with the object being cloned. If that state is mutable,
you don’t have two independent objects. If you modify one, the other
changes as well. And all of a sudden, you get random behavior.
标签:java,object,instance,inheritance,clone
来源: https://codeday.me/bug/20191004/1853020.html