Search code examples
javaarraysshallow-copy

Deep Copy and Shallow Copy Java


I am studying for a java exam and what I found out practically differed from what is taught in theory.

Below is code:

    StringBuilder num3[]= new StringBuilder[2];
    num3[0]= new StringBuilder("Pine");
    num3[1]= new StringBuilder("Oak");
    StringBuilder num4[] = new StringBuilder[2];
    System.arraycopy(num3, 0, num4, 0, 2);
    System.out.println(num3[0]==num4[0]);
    System.out.println(num4[0]);
    num3[0] = new StringBuilder("Choc"); 
    System.out.println(num3[0]);
    System.out.println(num4[0]);

The output is:

true
Pine
Choc
Pine

The true statement indicates that it is a shallow copy as num4[0] references the same object of num3[0]. But when I change the num3[0] I expected num4[0] to change too.

Why would this be happening if it is a shallow copy?

Is it because the new object is being created for num3[0] and the old "Pine" StringBuilder object is being referenced by the num4 array?

If so could anyone give me an example for System.arraycopy where this shallow copy is evident?

Thanks in advance, Chrisyopher


Solution

  • After the System.arraycopy, the two arrays are indeed shallow copies of each other. That is, you had a copy of the references to the StringBuilders. The objects referred to are the same.

    num3:  [ refA, refB ]                        num4: [ refA, refB ]
               |    |                                      |     |
               |    `-------> StringBuilder("Oak") <-------+-----' 
               `------------> StringBuilder("Pine") <------'
    

    But then you change the reference in num3[0] to point to a new StringBuilder:

    num3:  [ refC, refB ]                        num4: [ refA, refB ]
               |    |                                      |     |
               |    `-------> StringBuilder("Oak") <-------+-----' 
               |              StringBuilder("Pine") <------'
               `------------> StringBuilder("Choc")
    

    The underlying objects haven't changed. All you've done is changed what's referencing them.


    System.arraycopy is just like having a for loop that copies the values in the arrays over, except it's much more efficient for large arrays (as modern CPUs have special instructions for bulk memory copying). You don't ever need it semantically; it's just a performance optimisation.