Search code examples
javashallow-copy

Why do the assignments to v, w behave differently?


I would expect a shallow copy on v and output 701 801, but I see 700 801. I cannot see a good explanation. If w is a shallow copy, why not v? Does an Integer assigned an Integer "rebox"?

class Scalar {
    Integer w;
    public String toString() { return String.valueOf( w ); }
}

public class Demo {
    public Integer v;
    public Scalar scal;

    Demo shallowCopy() {
        Demo scopy = new Demo();
        scopy.v = this.v;  // <- Given this I would 701 from 
        scopy.scal = this.scal;
        return scopy;
    }

    public String toString() { return String.valueOf(v) + " " + scal.toString();  }

    public static void main( String[] args ) {
        Demo d1 = new Demo();
        d1.v = 700;
        d1.scal = new Scalar();
        d1.scal.w = 800;
        Demo d2 = d1.shallowCopy();
        d2.v = 701;
        d2.scal.w = 801;
        System.out.println( d1 );
    }
}

Solution

  • d2.v = 701; replaces the whole Integer.

    Your shallow copy copies the reference to the Integer object held by d1, so d2.v has reference to the Integer object itself, not reference to d1.v.

    On the other hand, d2.scal is not replaced. Therefore, d1.scal is equal to d2.scal because they are exactly the same object. If you change scal.w, it changes the value in that object, which will change for both d1.scal and d2.scal. Meanwhile, overwriting d2.v changes the reference, but does not change the object pointed to by d2.v itself, hence not d1.v.