Reputation: 113
I read somewhere that System.arraycopy
does create a new copy for primitive data types and shallow copy for object references.
so, that I started the experiment that with below code
//trying with primitive values
int a[] ={1,2,3};
int b[] = new int[a.length];
System.arraycopy(a,0,b,0,a.length);
b[0] = 9;
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
//now trying with object references
Object[] obj1 = {new Integer(3),new StringBuffer("hello")};
Object[] obj2 = new Object[obj1.length];
System.arraycopy(obj1,0,obj2,0,obj1.length);
obj1[1] = new StringBuffer("world");
System.out.println(Arrays.toString(obj1));
System.out.println(Arrays.toString(obj2));
and the output was
[1, 2, 3]
[9, 2, 3]
[3, world]
[3, hello]
But what I expected was
[1, 2, 3]
[9, 2, 3]
[3, world]
[3, world]
from the above code, I understood that System.arraycopy
does deep copy for object references
If so, how obj1[0] == obj2[0]
gives true
Upvotes: 4
Views: 4513
Reputation: 22442
I understood that System.arraycopy does deep copy for object references If so, how obj1[0] == obj2[0] gives true
No, you are wrong, it doesn't perform the deep copy. Because obj1[0] == obj2[0]
refer the same integer objects (i.e., references stored in the arrays at index '0') inside the both the arrays, so you are getting the answer as true
. Also, you can compare obj1[1] == obj2[1]
which returns false
, because both the StringBuffer
references are different.
Also, the other point is that System.arrayCopy
does only a shallow copy (simply copies the references/values from one array to another), you can refer here on this.
Upvotes: 0
Reputation: 393946
System.arraycopy
does shallow copy, which means it copies Object
references when applied to non primitive arrays.
Therefore after System.arraycopy(obj1,0,obj2,0,obj1.length);
, obj1[0]==obj2[0]
and obj1[1]==obj2[1]
, since both arrays hold references to the same Object
s.
Once you assign a new value to obj1[1]
, obj1[1]
no longer refers to the same StringBuffer
instance as obj2[1]
. That's why the outputs of Arrays.toString(obj1)
and Arrays.toString(obj2)
are different.
If instead of
obj1[1] = new StringBuffer("world");
you would write
obj1[1].setLength(0);
obj1[1].append("world");
both print statements would output [3, world]
, since both arrays would still refer to the same StringBuffer
instance.
Upvotes: 4
Reputation: 34638
You have a misconception.
Once you do
obj1[1] = new StringBuffer("world");
You have replaced the reference in obj1[1]
. Now the two arrays contain different references to different objects.
If you want to see that what was copied was the actual reference, you should try instead:
obj1[1].setLength(3);
Now both obj1[1]
and obj2[1]
should contain the string hel
, because you did not replace the reference but rather changed the content.
Upvotes: 5
Reputation: 73568
No, it's shallow copy for references.
First you create the reference to a new StringBuffer("hello")
, then you make a shallow copy of that. So you've got 1 StringBuffer
, but 2 references to it.
Finally you replace the other reference with a completely new StringBuffer("world")
.
Upvotes: 1