繁体   English   中英

使用new关键字和副本构造函数而不是super.clone()的Java clone()方法

[英]Java clone() method using new keyword and a copy constructor instead of super.clone()

在网上寻找如何多态复制对象的深层副本时,我找到了一种解决方案 ,声称可以解决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);
    }

    …
}

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

根据clone()方法文档 ,似乎此方法的所有“合同”都不是绝对要求,并且“返回的对象应通过调用super.clone() ”只是一个约定。

那么,此实现实际上不正确吗? 为什么?

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

谢谢,彼得

您正在尝试通过实现可克隆的接口来克隆,但不遵循建议的克隆协议。

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

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

还想指出的是,使用拷贝构造函数代替可克隆接口是更面向对象的方法。

那么,此实现实际上不正确吗? 为什么?

这是不安全的,因为删除了CloneNotSupportedException。

如果大脑不是可克隆的,那么新的人将没有大脑:)如果您的对象结构中有一个不受控制的对象(无法访问源代码)怎么办?

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

因为并非所有对象都只能从相似对象中克隆。 通常,有些环境对象比该对象的现有邻居对象更了解该特定新对象的外观。

该方法的缺点(除了删除CloneNotSupportedException的事实之外)是,如果子类调用super.clone()它们将获得Person的实例,而不是他们自己期望的类的实例。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM