Unravel › Java concepts › OOP and types
Copying objects: clone and copy constructors
Assigning an object (b = a) copies the reference, not the object.
Learn these first
At a glance
Shallow copy: photocopying a page that says "see the shared drawer": both copies still point to the same drawer.
- 1int[] b = a.clone() or Arrays.copyOf(a, a.length) makes a new array with the same elementsnew ArrayList<>(list) makes a new list holding the same element objects.
- 2A shallow copy duplicates only the outer object; the inner objects are sharedChanging a shared inner object shows up in both copies.
- 3A deep copy duplicates the inner objects too, usually with a copy constructor or a method that copies recursively
- Object.clone() is awkward: the class must implement the marker interface Cloneable, clone is protected, it skips constructors, and the default is shallow
- For immutable objects no copy is needed at all, which is the biggest argument for immutability
- Object.clone() is a native method that copies the object's memory block field by field without running a constructor
import java.util.*;public class Basket { private final List<String> items = new ArrayList<>(); public Basket() {} public Basket(Basket other) { this.items.addAll(other.items); } public int[] snapshot(int[] counts) { return Arrays.copyOf(counts, counts.length); } public int[] fast(int[] counts) { return counts.clone(); }}- line 6 uses copyOf, the core of Copying objects: clone and copy constructors
- line 7 uses clone, the core of Copying objects: clone and copy constructors
Read the full explanation (about 1 min)
Assigning an object (b = a) copies the reference, not the object. To get an independent copy you need clone(), a copy constructor or a library call, and you must decide how deep the copy goes.
A mental model
Shallow copy: photocopying a page that says "see the shared drawer": both copies still point to the same drawer. Deep copy: also making a new drawer with copies of the contents.
How it works
int[] b = a.clone() or Arrays.copyOf(a, a.length) makes a new array with the same elements. new ArrayList<>(list) makes a new list holding the same element objects.
A shallow copy duplicates only the outer object; the inner objects are shared. Changing a shared inner object shows up in both copies.
A deep copy duplicates the inner objects too, usually with a copy constructor or a method that copies recursively.
Going deeper
Object.clone() is awkward: the class must implement the marker interface Cloneable, clone is protected, it skips constructors, and the default is shallow. Most style guides recommend a copy constructor (new Order(other)) or a static factory instead.
For immutable objects no copy is needed at all, which is the biggest argument for immutability.
Defensive copies protect a class: copy mutable arguments on the way in and mutable fields on the way out, or callers can change your private state.
Under the hood
Object.clone() is a native method that copies the object's memory block field by field without running a constructor. Arrays have their own public clone(), and System.arraycopy is an intrinsic that compiles to a fast memory copy.
Common mistakes
- Believing
b = acopies an object. - Cloning a collection of mutable objects and expecting independent elements.
- Returning an internal array or list directly from a getter.
How Unravel recognises it
When you paste code, Unravel looks for these signs of copying objects: clone and copy constructors. Spotting them yourself is a good habit when you read unfamiliar code:
- Types:
Cloneable - Method calls:
clone()Arrays.copyOf()Arrays.copyOfRange()System.arraycopy()copyOf() - Method names you declare:
clone()
Part of a learning path
- Object-oriented Java in depth · previous: The Object class: toString, getClass, hashCode · next: Enums with fields and behaviour
Related concepts
Frequently asked questions
What is Copying objects: clone and copy constructors?
Assigning an object (b = a) copies the reference, not the object. To get an independent copy you need clone(), a copy constructor or a library call, and you must decide how deep the copy goes.
What are the most common mistakes with Copying objects: clone and copy constructors?
Believing b = a copies an object. Cloning a collection of mutable objects and expecting independent elements. Returning an internal array or list directly from a getter.
How can I see Copying objects: clone and copy constructors in real code?
Paste your own Java into Unravel and it will point out where copying objects: clone and copy constructors appears, explain how it works at the detail level you choose, and draw the flow of the code around it.