Effective Java:分析clone()方法

Gee*_*eek 18 java clone cloneable

请考虑以下有效Java项目11(明智地覆盖克隆),其中Josh Bloch正在解释clone()合同的错误.

这份合同存在许多问题."没有被称为构造函数"的规定过于强烈.一个行为良好的克隆方法可以调用构造函数来创建正在构建的克隆内部的对象.如果类是final,clone甚至可以返回由构造函数创建的对象.

有人可以解释Josh Bloch在第一段中所说的"如果类是final,clone甚至可以返回由构造函数创建的对象".这里final有什么关系clone()

Mat*_*att 22

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

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

通过这种方式,您可以继承超类中的克隆行为.人们普遍认为clone()操作的结果将根据调用它的对象返回正确的实例类型.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
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Jor*_*dão 20

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


Mar*_*nik 6

类不必提供自己的实现,clone以便可克隆.它可以将其委托给它的可克隆超类.接下来是:clone必须始终返回与调用它的实例相同的类的实例.如果调用显式构造函数,则无法在所描述的情况下实现.如果课程覆盖clone是最终的,另一方面,这将是好的.