Skip to content

Cloneable and clone()

Cloneable is a marker interface in Java (no methods). If a class implements Cloneable, it is allowed to use the default cloning behavior from Object.clone().

Stage 1advanced1 min read

What is Cloneable?

Sometimes you need a copy of an object. Cloneable is a marker interface: it has no methods. It is only a label that tells Object.clone() “copying this class field by field is allowed.” Without the label, Object.clone() throws CloneNotSupportedException.

Cloneable is a permission flag, not a full copying tool. The class still has to write its own public clone() method. This is one reason many people prefer copy constructors (a constructor that takes another object) or named factory methods. They are easier to use safely.

clone() in Object makes a shallow copy. It creates a new object and copies the field values. A field that holds a reference (another object or a list) is copied as the same reference. So the copy and the original share that inner object. If one changes the shared list, the other sees it. For a fully independent copy, write a deep copy yourself inside clone().

Why use it?

Sometimes creating a new object is expensive, for example it needs heavy setup or database calls. If you only want a copy with small changes, cloning can be cheaper than new plus copying fields by hand. The Prototype pattern uses this: keep a “master” object and clone it whenever you need a copy.

Example

interface EmailTemplate extends Cloneable {
    EmailTemplate clone();
    void setContent(String content);
}

class WelcomeEmail implements EmailTemplate {
    private String subject;
    private String content;

    public WelcomeEmail() {
        this.subject = "Welcome";
        this.content = "Hi there!";
    }

    @Override
    public WelcomeEmail clone() {
        try {
            // Shallow copy: new WelcomeEmail with same subject/content values
            return (WelcomeEmail) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("Clone failed", e);
        }
    }

    @Override
    public void setContent(String content) {
        this.content = content;
    }
}

Usage:

EmailTemplate master = new WelcomeEmail();
EmailTemplate copy = master.clone();  // Copy, no heavy constructor
copy.setContent("Hi Alice!");         // Change only the copy
// master unchanged; copy is independent (for primitive/String fields)

Important

  • Always return a clone from a registry, not the original, so the “master” stays unchanged.
  • If an object has nested mutable state (things that can change, such as lists or other objects), copy those inside clone() too (deep copy). Then the clone is fully independent.

Where you see it in this repo

  • PrototypeDesignPattern/After: EmailTemplate extends Cloneable, and WelcomeEmail.clone() uses super.clone(). EmailTemplateRegistry.getTemplate(type) returns templates.get(type).clone(), so clients get copies, not the stored prototype.

In this topic

Done with this topic?

How well do you know it?

PreviousException handling