In Java, what is a shallow copy?
Asked Answered
G

11

63

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

Genethlialogy answered 24/7, 2009 at 3:32 Comment(1)
Okay. It looks like the takeaway is that a Java shallow/deep copy is the same as the rest of the programming worlds, it's just the android 1.5 java.util.Calendar.clone() documentation is just wrong. clone() is a deep copy, not a shallow copy.Genethlialogy
A
99

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
Armada answered 24/7, 2009 at 3:50 Comment(4)
What happens if you make a change to the shallow copy? Will it change the shallowly copied reference?Leeke
Depends. newFoo.bar=newBar will only change newFoo's bar, not foo's. But newFoo.bar.avalue=1 would change both.Armada
what is Bar here? in 'private Bar myBar'Orpine
Just to say: equals() is a method of Object class. == should be used during reference comparison. == checks if both references point to the same location or not. equals() method should be used for content comparison.Compressor
S
21

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.

Sandhog answered 24/7, 2009 at 3:38 Comment(3)
This is a Java question not a C / C++ question, so talk of memory segments is misleading.Incommode
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.Sandhog
Relax, Stephen...for people coming from a C/C++ background, Chathuranga's answer actually helps. It is good to have different perspectives of the same issue.Aragonite
A
8

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.

Altman answered 24/7, 2009 at 3:43 Comment(1)
thats not right . if you are doing Object B = A , you are aliasing A. This is not shallow copy , rather this is just an assignment. if you do A.clone() and assign it to B , that would be the correct definition of a shallow copy.Pl
G
3

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.

Garboil answered 24/7, 2009 at 3:38 Comment(0)
P
2

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".

Parenthood answered 24/7, 2009 at 5:10 Comment(0)
D
2

SHALLOW COPY is PASS-BY-REFERENCE ... DEEP COPY is PASS-BY-VALUE … The context is different, but the process is exactly the same. First remember that in Java method calling, primitives are passed by value, while objects are passed by reference (in other languages, objects may also be passed by value). Now, in Java, when the caller passes a primitive to the called method, the called method simply clones it as a new local variable, which is a deep copy. While if an object is passed, the called method will only make a new local reference to the same object, which is shallow copy. If you understand calling, you understand deep/shallow copy, & vice versa.

Driggers answered 13/10, 2019 at 2:19 Comment(2)
Can you explain this a bit more? Pass by value or by reference is usually used in the context of method calls, not of cloning.Backwash
You should rather edit your question instead of adding comments. Not all comments may be initially seen. Put everything in one place, in the answer.Backwash
O
1

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().

Octans answered 24/7, 2009 at 3:38 Comment(3)
The documentation is from the latest Android 1.5 SDKGenethlialogy
Note clone() ought not to call a constructor according to Object.clone() spec.Wilden
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.Octans
F
1

First of all, the Javadoc of ArrayList is somewhat wrong if we are talking about one-dimensional arrays, as it uses the method copyOf in Arrays. So clone() gives back a one-dimensional copy, at least since 1.5 (I didn't test further)! So that's what "shallow" means in Java: one-dimensional

You can read more here: http://www.javapractices.com/topic/TopicAction.do?Id=3. So clone() is no shallow copy! If you want a real shallow copy of a one-dimensional array, just reference it:

Array a = new Array();
Array b = a;                    //a is only a shallow copy, nice for synchronisation

Arrays in Java are tricky, also because Java does pass-by-value, but the values of arrays are only their pointers! In the other hand this allows us to synchronize the objects, which is a great thing. Still, there are some problems if you use arrays within arrays (or ArrayLists), because a clone() of the container array (or ArrayList) won't copy their values, only their references! So you simply shouldn't put any arrays into an array, you should only deal with objects in an array!

And Javadoc is difficult to understand sometimes, so give testing a try...

Have fun!

Fill answered 20/10, 2012 at 7:38 Comment(0)
L
1

A shallow copy just copies the object reference into the target reference. It does not create a new object on the heap. By default, Java does shallow cloning using clone() function.

To get a new object on the heap, one has to perform deep cloning which can be implemented by Serialization and De-serialization.

Latishalatitude answered 5/4, 2017 at 14:2 Comment(1)
@Akansha : Could you please share the code on above theory you have mentioned. So it will easy to understand how to perform deep cloning with Serialization and De-serialization. and also shallow copySauterne
L
1

In a shallow copy,the clone object has a copy of primitive values but the object references refer to the same objects as the original copy. Shallow Copies have a significant drawback, cloned object and original copy refer to the same address object. Any change that cloned object makes in address object will also be reflected in original copy, which is an unwanted behaviour. What we really wanted is two separate copies of user object. Deep copying comes to our rescue for this kind of situation.

Deep copying clones not just the primitive values, it also creates copies of object references.

You can have a look at working example on this at here :https://codingninjaonline.com/2017/11/09/deep-vs-shallow-copy/

Limited answered 9/11, 2017 at 9:42 Comment(0)
T
1

Shallow Copy : In this cloning any changes to Cloned Object is reflected to Original Object also.

Deep Copy : In this cloning a separate cloned memory is alloted which means any changes to cloned object will not be reflected to original object.

Triley answered 16/7, 2019 at 4:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.