BackendBench
Coffee

Unravel › Java concepts › Design patterns and architecture

Java language

Builder pattern

A builder creates a complex object step by step with readable, named steps (Pizza.builder().size(12).cheese(true).build()), instead of one constructor with many positional parameters.

Learn these first

At a glance

Mental model

Ordering at a sandwich counter: you say each choice in turn, in any order, and only at the end they put it together and hand it over.

What happens, in order
  1. 1A nested static Builder class holds the fields with setter-like methods that return this, so calls chain: .name("x").qty(2)build() validates and creates the final object.
  2. 2The target class gets a private constructor taking the builder, so objects can only come from the builder and can be immutable
  3. 3Lombok @Builder generates all that; the JDK itself uses builders in HttpRequest.newBuilder(), Stream.builder(), ProcessBuilder, Locale.Builder
  4. 4Use it when there are many optional parameters, or when the object must be valid and immutable once built
Remember
Watch out
Skipping validation in build()Reusing a builder after build() and sharing mutable state between productsWriting a builder for a class with two fields
Example (highlighted lines explain it)
public class Pizza {  private final int size; private final boolean cheese;  private Pizza(Builder b) { this.size = b.size; this.cheese = b.cheese; }  public static Builder builder() { return new Builder(); }  public static class Builder {    private int size = 12; private boolean cheese;    public Builder size(int size) { this.size = size; return this; }    public Builder cheese(boolean cheese) { this.cheese = cheese; return this; }    public Pizza build() {      if (size <= 0) throw new IllegalStateException("size must be positive");      return new Pizza(this);    }  }}
  1. line 3 uses Builder, the core of Builder pattern
  2. line 4 uses Builder, the core of Builder pattern
  3. line 5 uses Builder, the core of Builder pattern
  4. line 7 uses Builder, the core of Builder pattern
  5. line 8 uses Builder, the core of Builder pattern
  6. line 9 uses build, the core of Builder pattern
Read the full explanation (about 1 min)

A builder creates a complex object step by step with readable, named steps (Pizza.builder().size(12).cheese(true).build()), instead of one constructor with many positional parameters.

A mental model

Ordering at a sandwich counter: you say each choice in turn, in any order, and only at the end they put it together and hand it over.

How it works

A nested static Builder class holds the fields with setter-like methods that return this, so calls chain: .name("x").qty(2). build() validates and creates the final object.

The target class gets a private constructor taking the builder, so objects can only come from the builder and can be immutable.

Lombok @Builder generates all that; the JDK itself uses builders in HttpRequest.newBuilder(), Stream.builder(), ProcessBuilder, Locale.Builder.

Use it when there are many optional parameters, or when the object must be valid and immutable once built.

Going deeper

Put validation in build() (required fields, combinations) so an invalid object can never exist. Make the builder itself not thread safe and short lived.

Compare alternatives: a record for few fields, static factory methods for named constructors, and the "telescoping constructor" anti-pattern that the builder avoids.

A copy builder (toBuilder()) is the idiomatic way to create a modified copy of an immutable object.

Under the hood

A builder is plain Java: just an object that collects values. The returned this enables the "fluent interface". Each chained call is a normal method call; the JIT usually inlines them so the cost disappears.

Common mistakes

  • Skipping validation in build().
  • Reusing a builder after build() and sharing mutable state between products.
  • Writing a builder for a class with two fields.

How Unravel recognises it

When you paste code, Unravel looks for these signs of builder pattern. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Builder pattern?

A builder creates a complex object step by step with readable, named steps (Pizza.builder().size(12).cheese(true).build()), instead of one constructor with many positional parameters.

What are the most common mistakes with Builder pattern?

Skipping validation in build(). Reusing a builder after build() and sharing mutable state between products. Writing a builder for a class with two fields.

How can I see Builder pattern in real code?

Paste your own Java into Unravel and it will point out where builder pattern appears, explain how it works at the detail level you choose, and draw the flow of the code around it.