How do I copy an object in Java?
I need clarification on the differences between deep copy, shallow copy, and clone in Java
Unfortunately, "shallow copy", "deep copy" and "clone" are all rather ill-defined terms.
In the Java context, we first need to make a distinction between "copying a value" and "copying an object".
In short, an assignment is "copying a value". To copy an object, something needs to use
Now for "shallow" versus "deep" copying of objects. Shallow copying generally means copying only one level of an object, while deep copying generally means copying more than one level. The problem is in deciding what we mean by a level. Consider this:
The normal interpretation is that a "shallow" copy of
The normal interpretation of a "deep" copy of
(People coming from a C / C++ background might say that a reference assignment produces a shallow copy. However, that's not what we normally mean by shallow copying in the Java context ...)
Two more questions / areas of uncertainty exist:
Finally, clone. Clone is a method that exists on all classes (and arrays) that is generally thought to produce a copy of the target object. However:
Here's what the javadoc says:
Note, that this is saying that at one extreme the clone might be the target object, and at the other extreme the clone might not equal the original. And this assumes that clone is even supported.
In short, clone potentially means something different for every Java class.
Some people argue (as @supercat does in comments) that the Java
The term "clone" is ambiguous (though the Java class library includes a Cloneable interface) and can refer to a deep copy or a shallow copy. Deep/shallow copies are not specifically tied to Java but are a general concept relating to making a copy of an object, and refers to how members of an object are also copied.
As an example, let's say you have a person class:
How do you clone objects of this class? If you are performing a shallow copy, you might copy name and put a reference to
A deep copy would mean that you recursively copy every member, so you would need to create a new
Although the above example is trivial, the differences between deep and shallow copies are significant and have a major impact on any application, especially if you are trying to devise a generic clone method in advance, without knowing how someone might use it later. There are times when you need deep or shallow semantics, or some hybrid where you deep copy some members but not others.
A shallow copy is nothing more than a reference to an existing object. Any changes you make to a shallow copy can be seen by other references to that object. Consider the following code:
b is now a "shallow copy" of a. Both a and b have two elements (1 and 2).
In Java, there is no precise definition for deep copy. There is an interface that permits a developer to define what clone means, but this is up to the whims of the developer. Deep copy and clone imply that instead of a reference to an object, you are getting a totally separate, distinct object.
Consider the above code sample. With a deep copy (or clone), the lists a and b would be distinct from each other. So, for a deep copy or clone, b.add() would not affect the list a. That is, a would still have a single element (1), and b would have two elements (1 and 2).
Alas, this may or may not be the case. There is an interface (Cloneable) that specifies the manner that a clone of a Cloneable object is created. How deep it goes depends on what the team that defined and implemented the class constitutes a clone. Deciding on what to make deep or shallow copies of on an object is not a trivial decision. There are some objects where making a deep copy does not make sense (such as a reference to a singleton), or are not efficient (such as a copy of a constant, such as a String).
The terms "shallow copy" and "deep copy" are a bit vague; I would suggest using the terms "memberwise clone" and what I would call a "semantic clone". A "memberwise clone" of an object is a new object, of the same run-time type as the original, for every field, the system effectively performs "newObject.field = oldObject.field". The base Object.Clone() performs a memberwise clone; memberwise cloning is generally the right starting point for cloning an object, but in most cases some "fixup work" will be required following a memberwise clone. In many cases attempting to use an object produced via memberwise clone without first performing the necessary fixup will cause bad things to happen, including the corruption of the object that was cloned and possibly other objects as well. Some people use the term "shallow cloning" to refer to memberwise cloning, but that's not the only use of the term.
A "semantic clone" is an object which is contains the same data as the original, from the point of view of the type. For examine, consider a BigList which contains an Array> and a count. A semantic-level clone of such an object would perform a memberwise clone, then replace the Array> with a new array, create new nested arrays, and copy all of the T's from the original arrays to the new ones. It would not attempt any sort of deep-cloning of the T's themselves. Ironically, some people refer to the of cloning "shallow cloning", while others call it "deep cloning". Not exactly useful terminology.
While there are cases where truly deep cloning (recursively copying all mutable types) is useful, it should only be performed by types whose constituents are designed for such an architecture. In many cases, truly deep cloning is excessive, and it may interfere with situations where what's needed is in fact an object whose visible contents refer to the same objects as another (i.e. a semantic-level copy). In cases where the visible contents of an object are recursively derived from other objects, a semantic-level clone would imply a recursive deep clone, but in cases where the visible contents are just some generic type, code shouldn't blindly deep-clone everything that looks like it might possibly be deep-clone-able.