Java:super.clone()方法和继承 [英] Java: super.clone() method and inheritance

查看:166
本文介绍了Java:super.clone()方法和继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Java中的 clone()方法有一个简单的问题,用作 super.clone()关于继承 - 我在父类中从按钮一直调用 clone()方法。

I have a quick question regarding the clone() method in Java, used as super.clone() in regard to inheritance - where I call the clone() method in the parent class all the way up from the button.

clone()方法应该返回此对象的副本,但是如果我在继承heirachy中有三个类并且调用 super .clone()三次,为什么不继承heirachy中的最高类,只是在类Object下,得到该类的副本返回?

The clone() method is supposed to return a copy of this object, however if I have three classes in an inheritance heirachy and call super.clone() three times, why doesn't the highest class in the inheritance heirachy, just under class Object, get a copy of that class returned?

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

Suppose we have three classes: A, B and C, where A -> B -> C (inherit = ->)

然后调用<$ c C类中的$ c> super.clone(),在B中调用 clone(),调用 super.clone( ),在A中调用 clone(),调用 super.clone()'this时间Object.clone()被调用'。为什么它不是从 Object.clone()返回的关于A类的这个对象的副本?这对我来说听起来很合乎逻辑。

Then calling super.clone() in class C, invokes clone() in B which calls super.clone(), invoke clone() in A which call super.clone() 'this time Object.clone() gets called'. Why is it not a copy of the this object with respect to class A that gets returned from Object.clone()? That sounds logical to me.

推荐答案

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

It sounds like there are at least two problems at work here:


  1. 听起来你对clone()通常如何实现感到困惑。

  1. It sounds like you're confused about how clone() normally gets implemented.

听起来你认为克隆是一个好主意(与使用复制构造函数,工厂或它们的等价物相比)。

It sounds like you're thinking that cloning is a good idea (vs. using a copy constructor, factories or their equivalent).

以下是实施示例克隆方法:

@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 )。

Note that the result of super.clone() is immediately cast to a Fruit. That allows the inheriting method to then modify the Fruit-specific member data (fBestBeforeDate in this case).

因此,对孩子的调用 clone()方法,虽然它会调用父母的克隆,但也会对新制作的副本添加自己的特定修改。在这种情况下,出现的是 Fruit ,而不是对象

Thus, the call to a child clone() method, while it will call the parents' clones, also adds its own specific modifications to the newly made copy. What comes out, in this case, will be a Fruit, not an Object.

现在,更重要的是,克隆是一个坏主意。复制构造函数和工厂提供了更直观,易于维护的替代方案。尝试阅读我附加到 Java Practices 链接的标题。示例:总结了一些问题。 Josh Bloch也有更长时间的讨论:绝对应该避免克隆。以下是关于他认为克隆是一个问题的优秀摘要段落:

Now, more importantly, cloning is a bad idea. Copy constructors and factories provide much more intuitive and easily maintained alternatives. Try reading the header on the Java Practices link that I attached to the example: that summarizes some of the problems. Josh Bloch also has a much longer discussion: cloning should definitely be avoided. Here is an excellent summary paragraph on why he thinks cloning is a problem:


对象的克隆方法非常棘手。它基于现场副本,而b $ b是超语言。它创建一个对象而不调用
构造函数。无法保证它保留了构造函数建立的不变量
。在
年间,Sun和Sun之外都出现了很多错误,这是因为如果你
只是反复调用super.clone,直到克隆了
对象为止,你有一个对象的浅表副本。克隆通常
与正在克隆的对象共享状态。如果该状态是可变的,
您没有两个独立的对象。如果您修改一个,其他
也会更改。而且突然之间,你会得到随机行为。

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:super.clone()方法和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆