Prototype Pattern in Java: Simple Guide with Real Example (2026)

Prototype Pattern in Java: Simple Guide with Real Example (2026)

Prototype Pattern in Java: Simple Guide with Real Example

Prototype Pattern is the simplest of the five creational patterns — but it hides a trap that catches many developers. The idea is easy: instead of creating a new object from scratch, just copy an existing one. But how you copy it makes a huge difference. In this guide, I will explain Prototype Pattern in plain words, walk through a real example, and show you the shallow vs deep copy trap that almost everyone falls into.

What is Prototype Pattern, in simple words?

Prototype Pattern is a way to create new objects by copying an existing one, instead of building them from scratch.

Here is the idea. Sometimes creating an object is a lot of work. You have to read configuration files, make network calls, load data from a database, and run complex setup code. If you need five similar objects, doing all that work five times is wasteful.

Prototype Pattern says: make the first object once. Then copy it as many times as you need.

The original object is called the "prototype." You "clone" it to get new objects. And here is the fun part — you can make small changes to each clone without affecting the others.

Think of it like a rubber stamp. You carve the stamp once, then press it on paper as many times as you want. The stamp is the prototype. Each impression is a clone.

Simple, right? But there is a trap hiding in the details, and we will get to it soon. First, let me give you a picture.

A real-life example: photocopying your ID

You have probably done this a hundred times.

Imagine you are filling out a form that needs a copy of your Aadhaar card, your PAN card, and your passport. What do you do?

You do not go to the government office and re-apply for a fresh Aadhaar card just to submit one. You take the original, put it on a photocopy machine, and press "copy." Thirty seconds later, you have a fresh copy.

Same for PAN card, same for passport. You copy them all.

Now map it to code:

  • The original document is your prototype.
  • The photocopy machine is Java's clone() method.
  • The copy is a new object with the same data.
  • Modifying the copy (like drawing a line on it) does not change the original.

That is Prototype Pattern in one picture. Make one, copy many.

But here is where it gets tricky. What if your original document has a photo attached with a staple? When you photocopy the document, does the photo also get copied?

In real life, no — the photocopy just shows the photo. But in code, this is exactly the shallow vs deep copy problem. We will get to it after the code walkthrough.

Building it in Java step by step

Let us build a simple example: a Book class with title, author, and a list of chapters. We will use Prototype Pattern to create variations quickly.

Step 1: Create the class and implement Cloneable

import java.util.ArrayList;
import java.util.List;

public class Book implements Cloneable {
    private String title;
    private String author;
    private List<String> chapters;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
        this.chapters = new ArrayList<>();
    }

    public void addChapter(String chapter) {
        chapters.add(chapter);
    }

    public void setTitle(String title) {
        this.title = title;
    }

    @Override
    public String toString() {
        return "Book {title='" + title + "', author='" + author + "', chapters=" + chapters + "}";
    }
}

Nothing special yet. Just a regular class with a few fields.

Step 2: Override the clone() method

Now we tell Java how to copy this object.

@Override
public Book clone() {
    try {
        return (Book) super.clone();
    } catch (CloneNotSupportedException e) {
        throw new RuntimeException("Clone failed", e);
    }
}

This calls super.clone() — Java's built-in copying mechanism. It creates a new object with the same field values. Simple.

Step 3: Use it

public class Main {
    public static void main(String[] args) {
        // Create the original book
        Book original = new Book("Java Basics", "Deep Singh");
        original.addChapter("Introduction");
        original.addChapter("Variables");
        original.addChapter("Loops");

        System.out.println("Original: " + original);

        // Clone it
        Book clonedBook = original.clone();
        clonedBook.setTitle("Java Advanced");

        System.out.println("Cloned:   " + clonedBook);
        System.out.println("Original: " + original);
    }
}

Output

Original: Book {title='Java Basics', author='Deep Singh', chapters=[Introduction, Variables, Loops]}
Cloned:   Book {title='Java Advanced', author='Deep Singh', chapters=[Introduction, Variables, Loops]}
Original: Book {title='Java Basics', author='Deep Singh', chapters=[Introduction, Variables, Loops]}

See what happened? The cloned book has its own title. Changing it did not affect the original. The author and chapters were copied over. This is what we wanted.

But wait — there is a hidden problem here. Let me show you.

The trap: shallow copy vs deep copy

Now let me add one more line to the example and watch what happens.

Book clonedBook = original.clone();
clonedBook.addChapter("Lambda Expressions");

System.out.println("Cloned:   " + clonedBook);
System.out.println("Original: " + original);

Output

Cloned:   Book {title='Java Basics', ..., chapters=[Introduction, Variables, Loops, Lambda Expressions]}
Original: Book {title='Java Basics', ..., chapters=[Introduction, Variables, Loops, Lambda Expressions]}

Wait, what? The original book also got "Lambda Expressions" added to its chapters?

That is the trap. Welcome to shallow copy.

What actually happened

When you call super.clone(), Java does what is called a shallow copy. It copies all the field values from one object to another — but if a field is a reference (like our List<String> chapters), it copies the reference, not the list itself.

So the original book and the cloned book both point to the same chapter list. When you add a chapter to one, you add it to both.

Here is the picture:

Shallow copy:

Original ─────────► [chapters list]
                        ▲
Cloned   ───────────────┘
(Both point to the same list)

This is the biggest source of bugs when using Prototype Pattern. Nobody warns you about it in most tutorials.

How to fix it: deep copy

A deep copy means copying the object and everything inside it. So the two books get their own chapter lists. Here is how:

@Override
public Book clone() {
    try {
        Book cloned = (Book) super.clone();
        // Manually clone the mutable fields
        cloned.chapters = new ArrayList<>(this.chapters);
        return cloned;
    } catch (CloneNotSupportedException e) {
        throw new RuntimeException("Clone failed", e);
    }
}

The key line is cloned.chapters = new ArrayList<>(this.chapters);. This creates a fresh list with the same contents. Now the two books have independent lists.

Let me show you the difference in a picture:

Deep copy:

Original ─────────► [chapters list A]
Cloned   ─────────► [chapters list B]  (Separate list with same data)

Run it again

Book clonedBook = original.clone();
clonedBook.addChapter("Lambda Expressions");

Output

Cloned:   Book {title='Java Basics', ..., chapters=[Introduction, Variables, Loops, Lambda Expressions]}
Original: Book {title='Java Basics', ..., chapters=[Introduction, Variables, Loops]}

Now the original book stays clean. That is what we wanted.

The rule of thumb

  • Shallow copy is fine if your object has only primitive fields (int, String, boolean, etc.)
  • Deep copy is necessary if your object has mutable fields (List, Map, arrays, or other custom objects)

Java's built-in clone() always does a shallow copy by default. You have to handle deep copy yourself.

When to use it (and when not to)

Good times to use Prototype Pattern

  • Creating an object is expensive — database reads, network calls, complex setup
  • You need many similar objects with slight variations
  • You want to create copies of an object without depending on its class
  • You are building something like a game where you spawn hundreds of nearly identical enemies or objects
  • You want to save an object's state and restore it later (like a "save game" feature)

Bad times to use Prototype Pattern

  • Your object is simple — just use new
  • Your object has deep nested structures that would be hard to clone correctly
  • You can use a Builder Pattern instead — sometimes it is cleaner
  • You do not actually need clones — sometimes a factory returning fresh objects is better

The rule I use: if creating the object is more than 10 lines of setup code, consider Prototype. If it is 3-4 lines, just create a new one.

Do not reach for Prototype just because you learned it. Reach for it when the cost of creation is real.

Where you will see it in real Java code

Prototype Pattern shows up in more places than you would expect. Here are some real uses.

  • Spring Framework — the prototype scope. Every time you ask the container for a prototype-scoped bean, it gives you a new instance. This is Prototype Pattern at work.
  • Game engines — when you spawn 100 identical enemies, the game clones a prototype enemy instead of building each one from scratch.
  • Document templates — starting a new document from a template. Copy the template, modify the copy.
  • UI component trees — cloning complex UI layouts that share structure but differ in data.
  • Java's clone() itself — the method is Java's built-in implementation of the pattern.
  • Apache Commons Lang — the SerializationUtils.clone() method uses serialization for deep copy.
  • Cache warm-up — loading a complex object once and cloning it for every user request.

See the pattern? Every one of these has the same idea: making the first object is expensive, but copying is cheap.

Common mistakes to avoid

1. Forgetting to implement Cloneable

If your class does not implement Cloneable, calling super.clone() throws CloneNotSupportedException. Java requires you to opt in.

Fix: Always add implements Cloneable to your class. It is a marker interface — no methods to implement.

2. Forgetting deep copy for nested objects

This is the trap we covered above. If your class has Lists, Maps, arrays, or other objects, shallow copy shares them between clones.

Fix: Override clone() and manually clone any mutable fields.

3. Not handling final fields

If your class has final fields that are mutable (like final List<String> list), you cannot reassign them in clone(). You will need to clear and re-add, or use a different approach.

Fix: Avoid final mutable fields if you plan to use cloning. Or write your own copy constructor.

4. Copying objects with non-cloneable fields

If your class has a field that is not Cloneable, the shallow copy will share that field's reference. You will need to handle it manually.

Fix: For un-cloneable fields, use serialization-based deep copy or write custom copy logic.

5. Using clone() when a copy constructor is cleaner

Java's clone() mechanism is famously messy. It has been called a design flaw by Joshua Bloch in Effective Java. Sometimes a copy constructor is cleaner.

public Book(Book other) {
    this.title = other.title;
    this.author = other.author;
    this.chapters = new ArrayList<>(other.chapters);
}

Fix: Consider a copy constructor instead of clone() when you want clarity. Same pattern, cleaner code.

Common questions

What is Prototype Pattern in simple words?

Prototype Pattern is a design pattern where you create new objects by copying an existing object (the prototype), instead of creating them from scratch. It is useful when creating an object is expensive or complex.

Why do we need Prototype Pattern in Java?

We need it when creating an object requires heavy work — like a database call, a network request, or complex initialization. If you already have a similar object, cloning it is faster and cheaper than building a new one.

What is the difference between shallow copy and deep copy?

Shallow copy duplicates the object but shares references to nested objects. Deep copy duplicates everything, including nested objects. If your object contains lists, maps, or other mutable objects, shallow copy can cause unexpected bugs. Use deep copy for full independence.

How do you implement Prototype Pattern in Java?

You implement the Cloneable interface and override the clone() method. For deep copy, you need to also clone nested objects manually or use serialization. Java's built-in clone() only does a shallow copy by default.

Is Prototype Pattern the same as Cloneable?

Not exactly. Cloneable is Java's built-in interface for cloning. Prototype Pattern is a design idea that uses cloning. You can implement Prototype without Cloneable, and you can use Cloneable without following Prototype Pattern.

When should I avoid Prototype Pattern?

Avoid it when your object is simple to create (just a few fields, no expensive setup). Also avoid it when your object has many nested objects that would require complex deep copy logic. In those cases, a builder or factory is a better choice.

Where to go next

You now understand Prototype Pattern better than most working developers. You know the pattern, the deep copy trap that catches everyone, and when it is actually worth using.

If you remember one thing, remember this: Prototype Pattern is about copying, not creating. Use it when creating is expensive and copying is cheap. But always check for nested objects — shallow copy is the silent bug.

You have probably used Prototype Pattern without realizing it. Spring's prototype scope, game engines, and UI frameworks all use it. Now you know what is going on under the hood.

If this helped, bookmark it. But the real learning happens when you type the code. Write a class with a List field, clone it, and try to modify the clone. Watch the original change too. That single exercise will teach you more about shallow copy than any tutorial.