How does Object.clone() work in Java, and what is the role of the Cloneable interface?
answer
- Cloneable = empty marker; clone lives on Object
- No Cloneable → CloneNotSupportedException
- Always super.clone(), never new
- Default = shallow (refs shared)
- Widen to public + covariant return
basics
~20 sclone() makes a copy of an object. To use it, your class must implement Cloneable; otherwise calling clone() throws CloneNotSupportedException. The default copy is shallow — it copies field values but not the objects they point to.
solid answer
~40 sObject defines a protected native clone() that creates a new object and copies each field's value bit-for-bit. Cloneable is a marker interface (no methods): it signals that clone() is legal. If a class does NOT implement Cloneable and you call clone(), Object.clone() throws CloneNotSupportedException. To expose cloning you typically override clone(), make it public, call super.clone() to get the field-copied instance, and return it. Because clone() is declared on Object as protected and returns Object, you usually narrow the access to public and use a covariant return type so callers don't cast. The default copy is shallow: primitive fields are copied by value, but reference fields share the same referenced objects with the original.
go deeper
Knows clone() copies an object, that Cloneable must be implemented, and that without it you get CloneNotSupportedException. Recognizes shallow vs deep at a high level.
Can write a correct clone(): implement Cloneable, call super.clone(), catch the exception, widen to public. Explains why the default copy is shallow and what 'shared reference' means.
Articulates why Cloneable is a flawed marker interface, the super.clone() subclass-correctness argument, covariant return types, and the boundary between shallow and deep copying. Can reason about when clone is acceptable vs a copy constructor.
Frames cloning as an API design problem: discusses how the broken contract leaks into class hierarchies, sets team conventions (prefer copy constructors/factories), and weighs interop constraints (e.g. arrays/legacy APIs that still rely on clone).
## What 'cloning' means Cloning is producing a *new* object that is a copy of an existing one. In Java the JDK's built-in mechanism is the `clone()` method declared on `java.lang.Object`: ```java protected native Object clone() throws CloneNotSupportedException; ``` Three things about that signature matter: - **`protected`** — by default you can't call `obj.clone()` from arbitrary code; a class must override and *widen* it to `public` to let outsiders clone it. - **`native`** — the actual copying is done by the JVM, not Java code. It allocates a new object of the exact runtime class and copies every field's value. - **`throws CloneNotSupportedException`** — a *checked* exception. ## The Cloneable marker interface `java.lang.Cloneable` is a **marker interface**: an interface with **no methods**. Its only job is to act as a flag. The contract is unusual: `Object.clone()` checks at runtime whether `this` is an instance of `Cloneable`. If it is **not**, `clone()` throws `CloneNotSupportedException`. So `Cloneable` does not *provide* the `clone` method (that lives on `Object`); it merely *enables* the existing one. This is widely considered a design mistake — a marker interface that changes the behavior of a protected method on a different class. ## A minimal correct clone ```java public class Point implements Cloneable { int x, y; @Override public Point clone() { try { return (Point) super.clone(); // JVM field-copy } catch (CloneNotSupportedException e) { throw new AssertionError(e); // can't happen: we are Cloneable } } } ``` Key rules: 1. **Always call `super.clone()`** — that is what asks the JVM to do the real per-field copy and to produce an object of the correct runtime class. Building the copy with `new Point(...)` instead breaks subclasses (a subclass calling `super.clone()` would get a `Point`, not the subclass). 2. **Catch `CloneNotSupportedException`** — since you implement `Cloneable` it cannot actually be thrown, so most code rethrows it as an unchecked error. 3. **Narrow access to `public`** and use a **covariant return type** (`Point` instead of `Object`) so callers need no cast. ## Shallow copy The default copy is **shallow**: each field is copied by value. For primitive fields (`int`, `double`, `boolean`…) that copies the actual value. For reference fields it copies the *reference* — the copy and the original then point to the **same** referenced object. So mutating that shared object through one clone is visible through the other. Deep copying (recursively copying referenced mutable objects) is a separate, manual step. ## Why people avoid clone Because of the broken `Cloneable` contract, the shallow-by-default behavior, the checked exception, and the fact that `clone()` bypasses constructors, *Effective Java* recommends preferring a **copy constructor** or **copy factory** instead (covered in a follow-up).
- Why must clone() call super.clone() rather than construct a new instance with new?super.clone() ultimately reaches Object.clone(), which the JVM uses to create an object of the actual runtime class and copy its fields. If a class used 'new ThisClass()' instead, a subclass that called super.clone() would receive an instance of the parent type, not the subclass — violating the clone contract that the returned object's class equals the original's.
- What happens if you call clone() on a class that does not implement Cloneable?Object.clone() throws CloneNotSupportedException at runtime, because it checks 'this instanceof Cloneable' before copying.
saying these in an interview costs you the question
- Thinking Cloneable declares the clone() method (it has no methods)
- Implementing clone() by calling 'new' instead of super.clone() (breaks subclasses)
- Believing the default clone makes a deep copy
- Forgetting that clone() is protected on Object and must be widened to be callable