简体   繁体   中英

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. 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):

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.

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.

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.

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.

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.

Your method is OK if you know that subclasses will not rely on Object.clone() (or if there is no subclass)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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