0

在网上搜索如何以多态方式对对象进行深层复制时,我找到了一个声称可以解决该方法的许多问题的解决方案clone(),例如无法克隆final字段。该解决方案在实现中结合了受保护的复制构造函数的使用clone(),基本上是这样的(从引用页面复制的示例):

public class Person implements Cloneable
{
    private final Brain brain; // brain is final since I do not want 
                               // any transplant on it once created!
    private int age;

    public Person(Brain aBrain, int theAge)
    {
        brain = aBrain; 
        age = theAge;
    }

    protected Person(Person another)
    {
        Brain refBrain = null;
        try
        {
            refBrain = (Brain) another.brain.clone();
            // You can set the brain in the constructor
        }
        catch(CloneNotSupportedException e) {}
        brain = refBrain;
        age = another.age;
    }

    public Object clone()
    {
        return new Person(this);
    }

    …
}

clone()方法Brain可以以类似的方式实现。

根据该方法的文档clone(),似乎该方法的所有“约定”都“不是绝对要求”,“返回的对象应通过调用获得super.clone()”只是一种约定。

那么,这个实现真的不正确吗?为什么?

如果它是正确的,为什么它没有成为一种设计模式?这有什么缺点???

谢谢,彼得

4

3 回答 3

1

您正在尝试通过实现可克隆接口进行克隆,但未遵循推荐的克隆合同。

您基本上是在使用复制构造函数创建新对象,我的问题是为什么您需要实现可克隆?

如果您正在实施可克隆,那么您必须遵守合同。当您在 clone 方法中使用复制构造函数时,我不会推荐这种方法,因为它的子类的克隆将不是子类的对象,而是 Person 类的对象。

还要指出的是,使用复制构造函数而不是可克隆接口是更面向对象的方法。

于 2013-04-03T16:34:55.000 回答
0

那么,这个实现真的不正确吗?为什么?

这不安全,因为 CloneNotSupportedException 被丢弃。

如果 Brain 不可克隆 new Person 将没有大脑 :) 如果您的对象结构中有一个您无法控制的对象(无法访问源)怎么办?

为什么它没有成为一种设计模式

因为并非所有对象都可以仅从相似对象中克隆出来。通常,有些环境对象比它现有的邻居对象更清楚这个特定的新对象会是什么样子。

于 2013-04-03T15:47:56.823 回答
0

这种方法的缺点(除了 aCloneNotSupportedException被删除的事实之外)是,如果子类调用super.clone()它们将得到一个实例Person而不是他们自己的类的实例,正如他们所期望的那样。

如果您知道子类不会依赖Object.clone()(或者如果没有子类) ,您的方法就可以了

于 2013-04-03T16:26:29.707 回答