有效的Java:克隆的分析()方法(Effective Java: Analysis of the

2019-06-26 08:57发布

考虑从有效的Java项目11以下(覆盖克隆明智),其中乔希布洛赫在解释什么是错的clone()的合同。

有许多与本合同的问题。 “没有构造被称为”供应是太强大了。 行为良好的克隆方法可以调用构造来创建内部构造中的克隆对象。 如果类是final的,克隆甚至可以返回一个构造函数创建的对象。

有人能解释乔希布洛赫在由第一段说:“如果类是finalclone甚至可以返回一个构造函数创建的对象。” 是什么final有做clone()这里?

Answer 1:

如果一个类不是终点, clone必须返回最派生类调用它。 不能用一个构造函数工作,因为clone不知道调用哪一个。 如果一个类是final的,它不能有任何的子类,所以有在克隆时调用它的构造没有危险。



Answer 2:

这是因为克隆()的典型实现如下所示:

public class MyClass implements Cloneable {
  protected Object clone() {
    MyClass cloned = (MyClass) super.clone();
    // set additional clone properties here
  }
}

通过这种方式,你可以继承您的超类中的克隆行为。 大家普遍认为,一个克隆()操作的结果将返回基于它被称为在对象上正确的实例类型。 IE浏览器。 this.getClass()

所以,如果一个类是final的,你不必担心一个子类调用super.clone(),并没有得到正确的对象类型回来。

public class A implements Cloneable {
    public Object clone() {
       return new A();
    }
}


public class B extends A {
    public Object clone() {
       B b = (B)super.clone(); // <== will throw ClassCastException
    }
}

但是,如果A是最终的,没有人可以延长它,因此它是安全的使用构造函数。



Answer 3:

类没有提供它自己的实现的clone ,以可复制。 它可以委派到其可复制的超类。 这里谈到的陷阱: clone必须始终作为实例它被称为上返回相同的类的实例。 那是不可能的描述的情况下实现,如果一个明确的构造函数被调用。 如果类overridng clone是最终的,而另一方面,这将是罚款。



Answer 4:

对于合同clone规定,“按照惯例,返回的对象应该通过调用获得super.clone ”。 如果您的类不是最终版本,返回一个构造函数调用得到的东西,调用super.clone()从子类将不会返回预期的结果(首先返回的对象的类型不会是子类的类型作为本地clone()方法将返回)。



Answer 5:

见Jorado答案。 这是解释。 在另外的克隆已在最后的领域问题,请参阅: http://en.wikipedia.org/wiki/Clone_%28Java_method%29#clone.28.29_and_final_fields

:你也应该在克隆阅读乔希采访http://www.artima.com/intv/bloch13.html



文章来源: Effective Java: Analysis of the clone() method