Java clone()方法是实现多态克隆的唯一方法吗?



我需要装备我的类多态克隆(深拷贝),即我需要这样的工作:

SuperType original = new SubType();
SuperType copy = original.clone();

其中original.clone()可以用任何机制替换来创建深度拷贝,而copy的实际类型应为SubType,因为original也是SubType

clone()方法和Cloneable接口是实现这一目标的唯一途径吗?工厂方法和复制构造函数不能使用,因为只有在运行时才知道实际的类,对吗?除了那些序列化-反序列化方法和Java深度克隆库之外,还有其他建议的方法吗?在我看来,Java深度克隆库比clone()方法更糟糕?

谢谢,切赫

实际上对象的clone()方法不允许你做任何多态调用,因为是protected。实现Cloneable也没有用,因为它不包含clone()方法。

可以通过为克隆类提供多态方法来进行多态克隆,而克隆类又调用复制构造函数。

abstract class SuperType {
    public SuperType(SuperType t) {
    }
    public abstract SuperType deepCopy();
}
class SomeType extends SuperType {
    SomeType(SomeType t) {
        //copy constructor
    }
    @Override
    public SomeType deepCopy() {                        
        return new SomeType(this);
    }
}
 ...
SuperType original = new SubType();
SuperType copy = original.deepCopy(); //the deepCopy is called on children classes

参见:

Joshua Block对克隆与复制构造器的看法

为了使您的代码工作,该代码要么在SuperType类或子类内,要么您的SuperType类型必须有一个公共clone()方法。公共clone()方法不会自动存在,您必须实现它。您可以将其命名为其他任何名称,例如copy()

你的问题,然后,是如何实现clone()(或无论你叫它)的方法,使它做多态克隆。

Java开发人员想要的方法是调用super.clone(),假设继承层次结构中的所有类都类似地实现clone()来执行多态克隆。这最终到达受保护的Object.clone()方法,该方法实现了多态克隆的魔力。注意,要使Object.clone()不抛出异常,您的类必须实现Cloneable接口。

然而,还有其他可能的方法。例如,假设所有子类都有一个默认构造函数,您可以执行类似this.getClass().newInstance()的操作。这将创建正确类的对象,但不会复制字段。你的clone方法需要复制所有的字段,子类必须覆盖你的clone方法来复制它们的字段,等等。请注意,在这种情况下是否实现Cloneable接口是无关的。

另一种方法是,假设该类是Serializable,序列化和反序列化this。这将创建一个多态克隆,其中包含所有可序列化的字段。

您可以简单地为SuperType添加一个复制方法,并在所有subtype中实现它

class SuperType {
    public SuperType copy() {
              ...
    }
}

如果您不喜欢Cloneable接口,您可以创建自己的接口。每个类将负责创建一个正确类型的新实例。

相关内容

最新更新