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

时间:2013-04-03 14:28:35

标签: java clone deep-copy cloneable

我需要为我的班级配备多态克隆(深层复制),即我需要这样的工作:

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

其中original.clone()可以替换为任何创建深层副本的机制,copy的实际类型应为SubType,因为original也是SubType 1}}。

clone()方法和Cloneable接口是实现此目的的唯一方法吗?工厂方法和复制构造函数不能使用,因为实际的类只在运行时才知道,对吗?除了那些序列化 - 反序列化方法之外还有其他任何建议的方法吗?Java deep-cloning library这是恕我直言,甚至比clone()方法更糟的黑魔法?

谢谢,彼得

4 个答案:

答案 0 :(得分:4)

实际上,对象的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's opinion on cloning vs. copy constructor

答案 1 :(得分:2)

为了让您的代码正常工作,该代码位于SuperType类或子类中,或者您的SuperType类型必须具有公共clone()方法。公共clone()方法不会自动存在,您必须实现它。你可以把它称之为其他任何事情,例如copy()

然后,您的问题是如何实现clone()(或任何您称之为)的方法,以便进行多态克隆。

Java开发人员打算采用的方式是调用super.clone(),假设继承层次结构中的所有类都类似地实现了clone()来执行多态克隆。这最终会进入受保护的Object.clone()方法,它可以实现多态克隆的神奇功能。请注意,要使Object.clone()不抛出异常,您的类必须实现Cloneable接口。

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

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

答案 2 :(得分:1)

您可以简单地将复制方法添加到SuperType并在所有子类型中实现

class SuperType {

    public SuperType copy() {
              ...
    }
}

答案 3 :(得分:0)

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