考虑从有效的Java项目11以下(覆盖克隆明智),其中乔希布洛赫在解释什么是错的clone()
的合同。
有许多与本合同的问题。 “没有构造被称为”供应是太强大了。 行为良好的克隆方法可以调用构造来创建内部构造中的克隆对象。 如果类是final的,克隆甚至可以返回一个构造函数创建的对象。
有人能解释乔希布洛赫在由第一段说:“如果类是final
, clone
甚至可以返回一个构造函数创建的对象。” 是什么final
有做clone()
这里?
考虑从有效的Java项目11以下(覆盖克隆明智),其中乔希布洛赫在解释什么是错的clone()
的合同。
有许多与本合同的问题。 “没有构造被称为”供应是太强大了。 行为良好的克隆方法可以调用构造来创建内部构造中的克隆对象。 如果类是final的,克隆甚至可以返回一个构造函数创建的对象。
有人能解释乔希布洛赫在由第一段说:“如果类是final
, clone
甚至可以返回一个构造函数创建的对象。” 是什么final
有做clone()
这里?
如果一个类不是终点, clone
必须返回最派生类调用它。 不能用一个构造函数工作,因为clone
不知道调用哪一个。 如果一个类是final的,它不能有任何的子类,所以有在克隆时调用它的构造没有危险。
这是因为克隆()的典型实现如下所示:
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是最终的,没有人可以延长它,因此它是安全的使用构造函数。
类没有提供它自己的实现的clone
,以可复制。 它可以委派到其可复制的超类。 这里谈到的陷阱: clone
必须始终作为实例它被称为上返回相同的类的实例。 那是不可能的描述的情况下实现,如果一个明确的构造函数被调用。 如果类overridng clone
是最终的,而另一方面,这将是罚款。
对于合同clone
规定,“按照惯例,返回的对象应该通过调用获得super.clone
”。 如果您的类不是最终版本,返回一个构造函数调用得到的东西,调用super.clone()
从子类将不会返回预期的结果(首先返回的对象的类型不会是子类的类型作为本地clone()
方法将返回)。
见Jorado答案。 这是解释。 在另外的克隆已在最后的领域问题,请参阅: http://en.wikipedia.org/wiki/Clone_%28Java_method%29#clone.28.29_and_final_fields
:你也应该在克隆阅读乔希采访http://www.artima.com/intv/bloch13.html