Understanding the Prototype Design Pattern in Java: Implementation, Use Cases, and Summary
This article explains the Prototype design pattern in Java, detailing its purpose, creation methods, implementation using Cloneable, example code with Person and ArrayList, Spring bean prototype usage, and discusses its advantages and drawbacks.
The Prototype pattern is a creational design pattern that enables fast object copying by cloning an existing instance.
In Java, objects can be created via four main approaches: using the new keyword, implementing Cloneable and overriding clone() , invoking Class.newInstance() through reflection, or via deserialization.
This article focuses on the second method—using Cloneable —which copies the binary representation of an object in memory, yielding a duplicate with identical state and higher efficiency than repeated new constructions.
Typical scenarios for applying the Prototype pattern include situations where object construction is costly in time or resources, where extensive data preparation or permission setup is required, or when many callers need independent copies of a heavily used object.
Implementation example:
@Data
public class Person implements Cloneable {
private String name;
private String country;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}Demonstration code:
@Slf4j
public class Main {
public static void main(String[] args) throws CloneNotSupportedException {
Person jack = new Person();
jack.setName("jack");
jack.setCountry("china");
log.info("Original object: {}", jack);
Person mason = (Person) jack.clone();
mason.setName("mason");
log.info("Cloned object: {}", mason);
log.info("Original object after clone: {}", jack);
}
}The output shows that mason is a complete copy of jack and can be modified independently, demonstrating the efficiency gain over creating a new instance.
Note: the default clone() provides a shallow copy—primitive fields are fully duplicated, while reference fields are copied as references, which may require custom deep‑clone logic for nested objects.
Usage case 1 – ArrayList cloning (shallow copy):
public class ArrayList
extends AbstractList
implements List
, RandomAccess, Cloneable, java.io.Serializable {
/** Returns a shallow copy of this ArrayList instance. */
public Object clone() {
try {
ArrayList
v = (ArrayList
) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
}Usage case 2 – Spring prototype beans: by configuring a bean with scope="prototype" , each getBean() call returns a new instance, effectively applying the Prototype pattern at the container level.
Advantages:
Higher performance by copying memory binary streams instead of invoking constructors.
Cloned objects retain the original state, simplifying object creation.
Disadvantages:
Every class must implement its own clone() method; changes to the class may require updates to cloning logic, violating the Open/Closed Principle.
Deep cloning requires manual implementation, which can be complex for objects with multiple nested references.
Architect's Guide
Dedicated to sharing programmer-architect skills—Java backend, system, microservice, and distributed architectures—to help you become a senior architect.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.