用Java克隆对象

这样做会调用Asub的clone方法吗? 或Asub是否正确克隆? 如果没有,有没有办法通过这种方法推动深度克隆Asub?

abstract class Top extends TopMost { protected Object clone() { Object obj = super.clone(); // deep copy and try catch } } abstract class A extends Top { protected Object clone() { Object obj = super.clone(); // deep copy and try catch } } class Asub extends A { protected Object clone() { Object obj = super.clone(); // deep copy and try catch } public void doSomethingNew() { } } abstract class TopMost { public void someMethod() { Top a = (Top) super.clone(); // more code here } } public class Main { public static void main(String... args) { Asub class1 = new Asub(); class1.someMethod(); } } 

通过允许实现super.clone()所有abstract子类基本上什么都不做(因为你的例子中的所有抽象类都什么都不做)并且只调用(最后) Object.clone()方法。

我的建议是允许所有具体类(如ASub)覆盖clone方法并使用复制构造函数 idiom来创建自己的精确克隆….

例如

 public abstract class TopMost { public TopMost(TopMost rhs) { } } public abstract class Top extends TopMost { public Top(Top rhs) { super(rhs); //whatever you need from rhs that only is visible from top } } public abstract class A extends Top { public A (A rhs) { super(rhs); //TODO: do rhs copy } } public class ASub extends A { public ASub(ASub rhs) { super(rhs); //TODO: copy other stuff here.... } public Object clone() { return new ASub(this); } } 

PS使TopMost 克隆

首先,请注意clone()接口已损坏 ,因此不应在新代码中使用。 最好是实现复制构造函数

但是,如果您确实需要这样做, TopMost正确的方法是实现Cloneable 。 为什么? 有效Java第2版,第11项:

那么Cloneable做了什么,因为它不包含任何方法? 它确定了Object的受保护clone实现的行为:如果一个类实现Cloneable ,则Object的clone方法返回该对象的逐个字段副本; 否则它会抛出CloneNotSupportedException 。这是一个非常非典型的接口使用,而不是一个被模拟的接口。 通常,实现接口会说明类可以为其客户做些什么。 在Cloneable的情况下,它修改了超类上受保护方法的行为。

此外, Asub.clone应该被public ,不受protected – 否则你不能从外界称呼它。 此外,如果您使用的是Java5或更高版本,则Asub.clone返回Asub而非Object (以及类似的超类)是合法且合乎需要的。

您没有在类中显示任何成员 – 各种类中的clone实现可能会有很大不同,具体取决于该类中的成员类型。 也就是说,如果一个类有任何可变成员,你需要仔细深度复制所有这些成员,否则最终会有不同的对象共享其内部状态。

但是,假设您的类只有原始字段或不可变字段,克隆按预期工作,尽管您的抽象类中有许多不必要的clone方法,所有这些方法super.clone()调用super.clone() – 您可能最好使用Asub.clone()只。

作为旁注,如果Top a = (Top) super.clone()不是拼写错误,则引入从基类到派生类的依赖关系,这不是一个好主意。

super.clone()的调用会禁用虚拟机制,因此它只调用Object.clone()