Search code examples
javaarraysclonedeep-copyshallow-copy

clone() and system.arracopy() of an array creates two arrays with different references in Java?


Firstly I have to say this is not a duplicate of deep copying vs shallow copying (clone) in Java. but it is related to that. I have read other posts on deep vs shallow copying in SO and while working on this, I found some problem with my understanding. Question is : clone() and system.arraycopy() gives different arrays in the below example. but they aren't supposed to?

I used array as a field in another example object below. There again I see they are different references for the arrays fields. The code is commented for easy following.

import java.util.Arrays;
import java.util.*;


class Example {
        public int foo;
        public int[] bar;

        public Example (int foo, int[] bar) {
         this.foo = foo; 
        this.bar = bar; 
        }
        public void setfoo(int foo){
            this.foo=foo;
        }
        public int[] getbar(){
            return bar;
        }
}
public class ClonevsDeepCopy {
    public static void main(String[] args){
        //Example 1
        StringBuffer[] arr = {new StringBuffer("abc"),new StringBuffer("def"),
                                     new StringBuffer("ghi")};
        StringBuffer[] arr2 = arr.clone();
        StringBuffer[] arr3 = new StringBuffer[3];
        System.arraycopy(arr, 0, arr3, 0, 2);
        //check for identity
        System.out.println(arr==arr2);
        System.out.println(arr==arr3);
        //End of example 1

        //Example 2
        /*this is equivalent of shallow copying which is clone()
         * The normal interpretation is that a "shallow" copy of eg1 
         * would be a new Example object whose foo equals 1 
         * and whose bar field refers to the same array as in the original; e.g.
         */
        Example eg1 = new Example(1, new int[]{1, 2});
        Example eg2 = new Example(eg1.foo,eg1.bar);
        System.out.println(eg1.bar==eg2.bar);
        eg1.setfoo(4);
        eg1.bar[0]=99;

        /*This is equivalent of deep coying
        The normal interpretation of a "deep" copy of eg1 would 
        be a new Example object whose foo equals 
        1 and whose bar field refers to a copy of the original array; e.g.
        */
        Example eg3 = new Example(eg1.foo,Arrays.copyOfRange(eg1.bar, 0, 2));
        System.out.println(eg3.bar==eg1.bar);
        //cloning on array
        Example eg4 = new Example(eg1.foo,eg1.bar.clone());
        System.out.println(eg4.bar==eg1.bar);
        //End of example 2




    }

}

Solution

  • There's nothing strange here.

    If arr1 is the result or arr.clone() then arr1!=arr but arr1[0]==arr[0] if it is defined. If arr1=arr is the assignment then arr1==arr.

    Details:

    We have 5 results:

    false at System.out.println(arr==arr2);:

    Nothing strange here, we're comparing the array references themselves, not the contents.

    false at System.out.println(arr==arr3);

    Nothing strange, different arrays.

    true at System.out.println(eg1.bar==eg2.bar);:

    Nothing strange, same references.

    Last two false:

    Again, we're performing some shallow copies. The elements are still equal references, but the arrays are different references.