سؤال

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

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

You are not changing num3[0], you are pointing it at something else, namely, a new StringBuilder object. num3[0] and num4[0] no longer point at the same object, hence why num4[0] doesn't change. The values of the references of the array are copied, but if you modify those values it won't affect the other array. What would affect it is if you modify the objects at which they point, not the references to those objects.

Think of num3[0] and num4[0] as two guys pointing at a bagpack. If you add stuff to the backpack, they will both point at something that has been changed. However, if you ask num3[0] to point at a TV, num4[0] will still be pointing at the backpack.

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?

Exactly.

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

I am not sure I understand this question. No copy, be it shallow or deep can have an influence on what you do after the copy.

But try the following:

num3[1].append("tree");
println(num4[1]);        // should be "Oaktree"

num3[0] and num4[0] are references to same object, so when you change the num3[0] it just changes where the num3[0] is pointing to and will not change where num4[0] is pointing.

System.out.println(num3[0]==num4[0]);

This returns true because both are pointing to same object but both are individual.

If you would have done something like

num3[0].append("something") and then you would have printed num3[0] and num4[0] then both would have been affected.

A shallow copy in this case is nothing else than a new reference to the object. You have the object Pine with one pointer to it stored int num3. Now you make a shallow copy (you create a new reference) that is stored in num4. You now have one Pine object with two references. When you assign Choc to num3 the number of references decreases by 1 and you effectively replaced the reference held by num3 with a different one. Pine was never changed in any way.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top