Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Prototype Pattern: Efficient Object Cloning in Java

Tech May 13 1

The Prototype pattern enables object creation by copying an existing instance—called a prototype—rather than instantiating classes directly. This approach is especially useful when object initialization is costly or when many similar objects are needed with minor variations.

A basic implementation involves defining a method that creates a new instance and copies the current object's state into it:

public class Item {
    private String id;
    private String name;
    private String description;

    public Item cloneManually() {
        Item copy = new Item();
        copy.id = this.id;
        copy.name = this.name;
        copy.description = this.description;
        return copy;
    }

    public void display() {
        System.out.println("ID: " + id + "; Name: " + name + "; Desc: " + description);
        System.out.println("-------------------------------------");
    }

    // Getters and setters omitted for brevity
}

While this works, Java provides built-in support for cloning through the Cloneable interface and the Object.clone() method. To use it, a class must implement Cloneable and override clone():

public class Item implements Cloneable {
    private String id;
    private String name;
    private String description;

    @Override
    public Item clone() {
        try {
            return (Item) super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

    // Other methods remain unchanged
}

This native cloning mechanism avoids constructor invocation and performs a bitwise copy of the object’s memory, offering better performance—especially when creating numerous instances in tight loops.

However, Object.clone() performs a shallow copy by default. For objects containing mutable reference types (e.g., collections), both original and clone will share the same referenced objects:

public class CatalogItem implements Cloneable {
    private String title;
    private List<String> tags = new ArrayList<>();

    public void addTag(String tag) {
        tags.add(tag);
    }

    @Override
    public CatalogItem clone() {
        try {
            CatalogItem copy = (CatalogItem) super.clone();
            // Shallow copy: tags list is shared
            return copy;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}

Modifying the tags list in the clone affects the original. To achieve a deep copy, referenced objects must also be cloned:

@Override
public CatalogItem clone() {
    try {
        CatalogItem copy = (CatalogItem) super.clone();
        copy.tags = new ArrayList<>(this.tags); // Deep copy of the list
        return copy;
    } catch (CloneNotSupportedException e) {
        throw new RuntimeException(e);
    }
}

When multiple prototypes exist and may change dynamically, a prototype registry can manage them:

public interface Prototype extends Cloneable {
    Prototype duplicate();
}

public class PrototypeRegistry {
    private static final Map<String, Prototype> prototypes = new HashMap<>();

    private PrototypeRegistry() {}

    public static void register(String key, Prototype proto) {
        prototypes.put(key, proto);
    }

    public static void unregister(String key) {
        prototypes.remove(key);
    }

    public static Prototype create(String key) {
        Prototype proto = prototypes.get(key);
        return proto != null ? proto.duplicate() : null;
    }
}

This registry allows clients to request new objects by key without knowing their concrete types.

The Prototype pattern is ideal when:

  • Many similar objects are required with slight differences.
  • Object construction is expensive or complex.
  • Class information is unavailable at runtime, but a sample instence exists.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.