views:

1487

answers:

7

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)?

A: 

The 1.6 docs document Calendar.clone as "Creates and returns a copy of this object." A literal shallow copy as specified by Object.clone wouldn't make any sense. Java uses the term "shallow copy" in a fairly typical sense.

Tom Hawtin - tackline
+1  A: 

Where are you getting this documentation?

The official Java 6 docs on java.sun.com simply have Calendar.clone() returning a copy of the object. No mention of shallow.

More generally, a shallow copy in Java is one where you get a new object reference but the new object holds (directly or indirectly) references to data in the original.

For example:

class MyClass{
  private List<Integer> innerList;

  public MyClass(List<Integer> list) { innerList = list; }

  //Some code...

  public Object clone(){
    return new MyClass(innerList);
  }
}

returns a shallow copy in its clone().

Kevin Montrose
The documentation is from the latest Android 1.5 SDK
Will
Note `clone()` ought not to call a constructor according to `Object.clone()` spec.
notnoop
Yes, yes, technically you should get an Object out of super.clone(); cast it to MyClass and then set the fields magically. That's alot more code to show though, and the crux of the question is the shallow/deep distinction.
Kevin Montrose
+2  A: 

Shallow copy is a just a set of pointers to the same memory locations. Actually it does not create a real copy so the memory usage is lower.

In a case of a deep copy, an exact copy of the memory segment is created and pointers are set to new memory locations. So theoritically the memory consumption should be twice in this case.

Chathuranga Chandrasekara
This is a Java question not a C / C++ question, so talk of memory segments is misleading.
Stephen C
Don't think that much high level. In whatever language you are dealing with physical hardware like memory and CPU. Even we dont use alloc, mallocs dont think we are not using memory in Java.
Chathuranga Chandrasekara
A: 

At a glance, the fields all appear to be value types, so whether it's shallow or deep will not make a difference in that case.

James M.
+3  A: 

A shallow copy is a copy of the reference pointer to the object, whereas a deep copy is a copy of the object itself. In Java, objects are kept in the background, what you normally interact with when dealing with the objects is the pointers. The variable names point to the memory space of the object. A shallow copy is made when you set one variable equal to another like so:

Object B = A;

A deep copy could be made by getting the properties of object A and putting them in a new object B.

Object B = new Object(A.getProperty1(), A.getProperty2()...);

This affects program behavior in that if you make a shallow copy and perform a task on it, that affects all shallow copies of the object. If you make a change to a deep copy, only that copy is affected. I hope this is detailed enough for you.

indyK1ng
+3  A: 

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;

a is 11
*b is 11
c is 10

KitsuneYMG
+1  A: 

It appears to be a mistake in the documentation. I don't see how anything that Android's Calendar.clone method does meets the typical definition (in Java or otherwise) of a "shallow copy".

jsight