简体   繁体   English

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

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

When searching the net for possibilities how to make a deep copy of an object polymorphically, I found a solution that claims to solve many issues with the clone() method, eg the impossibility to clone final fields. 在网上寻找如何多态复制对象的深层副本时,我找到了一种解决方案 ,声称可以解决clone()方法的许多问题,例如无法克隆final字段。 The solution combines the use of a protected copy constructor inside the clone() implementation and basically goes like this (example copied from the referenced page): 该解决方案在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);
    }

    …
}

The clone() method of Brain may be implemented in a similar way. Brainclone()方法可以类似的方式实现。

Based on the documentation of the clone() method , it seems that all "contracts" of this method 'are not absolute requirements' and that 'the returned object should be obtained by calling super.clone() ' is just a convention. 根据clone()方法文档 ,似乎此方法的所有“合同”都不是绝对要求,并且“返回的对象应通过调用super.clone() ”只是一个约定。

So, is this implementation actually incorrect? 那么,此实现实际上不正确吗? Why? 为什么?

And if it is correct, why it did not become a design pattern? 如果正确,为什么它没有成为设计模式? What are the downsides of this??? 这有什么缺点???

Thanks, Petr 谢谢,彼得

You are trying to clone by implementing cloneable interface but not following recommended contracts of cloning. 您正在尝试通过实现可克隆的接口来克隆,但不遵循建议的克隆协议。

You are basically creating new object using copy constructor, my question is then why do you need to implement cloneable? 您基本上是在使用复制构造函数创建新对象,那么我的问题是为什么您需要实现可克隆的?

If you are implementing cloneable then you must respect the contracts. 如果要实现可克隆,则必须遵守合同。 When you use copy constructor inside clone method then i will not recommend this approach simply because clone of it child class will not be an object of child class and intstead will be an object of Person class. 当您在克隆方法中使用复制构造函数时,我将不推荐这种方法,因为它的子类的克隆将不是子类的对象,而代替将是Person类的对象。

Also want to point out that, using copy constructor instead of cloneable interface is more object oriented approach. 还想指出的是,使用拷贝构造函数代替可克隆接口是更面向对象的方法。

So, is this implementation actually incorrect? 那么,此实现实际上不正确吗? Why? 为什么?

It's not safe because CloneNotSupportedException is dropped. 这是不安全的,因为删除了CloneNotSupportedException。

If Brain is not clonable new Person will have no brain :) What if there is an object in your object structure that you are not controlling (no access to sources)? 如果大脑不是可克隆的,那么新的人将没有大脑:)如果您的对象结构中有一个不受控制的对象(无法访问源代码)怎么办?

why it did not become a design pattern 为什么它没有成为设计模式

Because not all objects can be cloned just from the similar object. 因为并非所有对象都只能从相似对象中克隆。 Usually, there are environment objects that known better what this particular new object will look like rather then its existing neighbor object. 通常,有些环境对象比该对象的现有邻居对象更了解该特定新对象的外观。

The downside of this method (beside the fact that a CloneNotSupportedException is dropped) is that if subclasses call super.clone() they will get an instance of Person instead of an instance of their own class as they may expect. 该方法的缺点(除了删除CloneNotSupportedException的事实之外)是,如果子类调用super.clone()它们将获得Person的实例,而不是他们自己期望的类的实例。

Your method is OK if you know that subclasses will not rely on Object.clone() (or if there is no subclass) 如果您知道子类将不依赖Object.clone() (或者如果没有子类),则方法是可以的

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

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