Search code examples
javacloneshallow-copy

In Java, what is a shallow copy?


java.util.Calendar.clone() returns "...a new Calendar with the same properties" and returns "a shallow copy of this Calendar".

This does not appear to be a shallow copy as answered here on SO. That question is tagged language-agnostic, Java does not seem to follow the language agnostic definition. As I step through the code I notice that the structure and the elements are copied to this new object, more than the language agnostic structure only.

In Java, what is a shallow copy?

How does it differ from a Java deep copy (if that exists)?


Solution

  • A shallow copy just copies the values of the references in the class. A deep copy copies the values. given:

    class Foo {
      private Bar myBar;
      ...
      public Foo shallowCopy() {
        Foo newFoo = new Foo();
        newFoo.myBar = myBar;
        return newFoo;
      }
    
      public Foo deepCopy() {
        Foo newFoo = new Foo();
        newFoo.myBar = myBar.clone(); //or new Bar(myBar) or myBar.deepCopy or ...
        return newFoo;
      }
    }
    
    Foo myFoo = new Foo();  
    Foo sFoo = myFoo.shallowCopy();  
    Foo dFoo = myFoo.deepCopy();  
    
    myFoo.myBar == sFoo.myBar => true  
    myFoo.myBar.equals(sFoo.myBar) => true  
    myFoo.myBar == dFoo.myBar => **false**  
    myFoo.myBar.equals(dFoo.myBar) => true  
    

    In this case the shallow copy has the same reference (==) and the deep copy only has an equivalent reference (.equals()).

    If a change is made to the value of a shallowly copied reference, then the copy reflects that change because it shares the same reference. If a change is made to the value of a deeply copied reference, then the copy does not reflect that change because it does not share the same reference.

    C-ism

    int a = 10; //init
    int& b = a; //shallow - copies REFERENCE
    int c = a;  //deep - copies VALUE
    ++a;
    

    Result:

    a is 11  
    *b is 11  
    c is 10