Search code examples
javacopy-constructordeep-copy

How can I make this copy constructor make a deep copy in java?


Heyho, look at this class

public class ComplexFoo {
  TreeMap<String, String> field1;
  double[] field2;

  public ComplexFoo() {
    field1 = new TreeMap<String, String>();
    field2 = new double[1];
  }

  public ComplexFoo(ComplexFoo cf){
    field1 = cf.field1;
    field2 = cf.field2;
  }

  public static void main(final String[] args) {
    ComplexFoo foo = new ComplexFoo();
    foo.field2[0] = 5.0;
    ComplexFoo bar = new ComplexFoo(foo);
    bar.field2[0] = 3.0;
    System.out.println(foo.field2[0]);
  }
}

This prints 3.0. I guess that is because my copy constructor copies only the references to the Array/Map, not the real data structures. What do I have to change to ensure deep copying?

If I write a class that takes a ComplexFoo as a field, will I have to write a copy constructor that uses ComplexFoos copy constructor or is there any kind of recursive deep copying mechanism I can use?


Solution

  • This is not a deep copy :

    public ComplexFoo(ComplexFoo cf){
       field1 = cf.field1;
        field2 = cf.field2;
    }
    

    The new created ComplexFoo instance refers to fields of the instance provided as parameter.

    To make a deep copy, you have to create new objects.

    TreeMap(Collection) does the job to create a new TreeMap from a Collection parameter. Note that you will not need to clone elements of the TreeMap as the types used as keys-values are actually immutable : <String, String>.
    And Object.clone() works well for one dimension array of number primitives values.
    So you could write :

    public ComplexFoo(ComplexFoo cf){
      field1 = new TreeMap<>(cf.field1);
      field2 = cf.field2.clone();
    }