سؤال

1. Definitions

- The class Object has a protected method clone which performs a shallow copy of the object, this method should be overridden in any class cloneable.

- There is a very particular Cloneable interface, when it's implemented in a class, it does not require the redefinition of the clone method.

- The declaration: class X implements Cloneable mentioned that class X can make a deep copy by calling the clone method which is the clone method of Object class or method provided by X.

1.1 I want to know if the definitions and rules described above are correct or not?

2. Example

When i want to make a deep copy of an object of a class, i used the following example:

class A implements Cloneable
{
    int valueA = 10;
    B b = new B();

    public A clone()
    {
        A result = new A();
        try
        {
            result = (A)(super.clone());
        }
        catch (CloneNotSupportedException e)
        {
        }
        return result;
    }
}

class B
{
    int valueB = 20;
}

public class Test
{
    public static void main(String[] args)
    {
        A a = new A();
        A a1 = a.clone();

        a1.valueA = 12;
        a1.b.valueB = 64;

        System.out.println("a.valueA = " + a.valueA);
        System.out.println("a1.valueA = " + a1.valueA);

        System.out.println("a.b.valueB = " + a.b.valueB);
        System.out.println("a1.b.valueB = " + a1.b.valueB);
    }
}

The output is :

a.valueA = 10

a1.valueA = 12

a.b.valueB = 64

a1.b.valueB = 64

I see that the deep copy is not well done because the valueB of object field b in object a is modified.

2.1 Why i get this ? is it due to my lack of comprehension of how should i make deep copy ? or the example is not enough ?

2.2 Can anyone give two correct examples of how should i make correctly shallow and deep copy ?

هل كانت مفيدة؟

المحلول

If you want to make a deep copy, then you need to also clone B when you clone A (or create another B instance using, for example, a copy constructor). Object.clone() simply creates a new instance of the objects containing references to the same objects as the object being cloned. It's a shallow copy. There is no way to correctly make a generic deep copy, simply because it often doesn't make sense:

  • cloning a String, for example, is useless since Strings are immutable
  • cloning a Socket, for example, makes no sense as a Socket is not clonable, since it represents an active side of a TCP connection, that can't be duplicated.

You should generally avoid using Cloneable. Prefer copy constructors instead. And favor immutability rather than deep copies.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top