Home > database >  Java deep clone and shallow clone
Java deep clone and shallow clone

Time:06-18

I thought the clone method below is a deep clone because it created a new object before copying the information over. However, it's a shallow clone. I'd like to understand why.

class FixedVector {
  public static int count;
  private Object data[];
  private int length = 0;
  public FixedVector(int size) {
    count  ;
    data = new Object[size];
  }
  public void add(Object ob) {
    if (length < data.length) {
      data[length  ] = ob;
    } else {
      throw new InsufficientSpaceException();
    }
  }

  public Object get(int index) {
    if (index < length) {
      return data[index];
    } else {
      throw new IndexOutOfBoundsException();
    }
  }
  public Object clone() {
    FixedVector c = new FixedVector(data.length);
    for (int i = 0; i < length;   i) {
      c.data[i] = data[i];
    }
    return c;
  }
  public static void main(String argv[]) {
    FixedVector n = new FixedVector(10);
    try {
      n.get(1);
    } catch (InsufficientSpaceException ie) {
      System.out.println("ERROR 1");
    } catch (IndexOutOfBoundsException oe) {
      System.out.println("ERROR 2");
    }
  }
}

CodePudding user response:

The clone() method is whatever you implement it to be1. If you want to implement deep copy, that is permitted. If you want to implement shallow copy, that is also permitted.

In this example, the author of FixedVector has explicitly implemented clone() as a shallow copy. Obviously the code will behave as written ... which is to shallow copy the data array.

Now ... if you were asking about what happens in this case:

public class FixedVector implements Cloneable {

    ...
    
    public Object clone() {
       return super.clone();
    }

}

that is more interesting. Here we are relying on the "magic" cloning behavior of Object.clone(). But this is defined to perform a shallow copy of the fields of the target object. So the clone would share the data array with it the object it was cloned from. (That's NOT what we would want, in this context, and hence FixedVector implements clone as as per your question.)


Note that the meaning of "deep" and "shallow" copy are very rubbery. In your example, there are actually (at least) 3 ways we could perform the copy:

  • The Object.clone() way gives a shared data array. That is a "shallow" copy.

  • The way in the question gives distinct data arrays but shared elements. That is a "deep-ish" copy.

  • Another way would be to clone the elements in the arrays. That would be a "deeper" copy. In your example, you could change

    c.data[i] = data[i];
    

    to

    c.data[i] = data[i].clone();
    

    But the actual depth depends on how clone is implemented by the element classes. That behavior is class specific.


1 - The Object.clone() javadoc talks about the "general intent" of the clone() method, but it makes it clear that it is permitted for a class to ignore this. However, I would say that it is inadvisable to ignore what the javadoc says.

  •  Tags:  
  • java
  • Related