Builder vs Constructor Overloading vs Setters
Fast recall
Quick revision
Core answer
Interview-ready guide
Interview answer
I choose the construction style from the object's rules. A constructor or record is best when the required inputs are few, ordered clearly, and the object is valid immediately. A builder helps when a call has many optional or same-typed values, when names improve readability, or when several values must be validated together before construction. Setters describe a different model: the object is allowed to change after creation and may temporarily be incomplete. There is no universal field-count cutoff. I compare call-site clarity, invariants, framework requirements, and whether mutation is part of the domain.
Builder vs Constructor Overloading vs Setters
Direct Answer
Use a constructor or record when the required inputs are few and clear. Use a builder when many named optional values, conditional validation, or multiple construction steps would otherwise make a call hard to read. Use setters only when the object's model is intentionally mutable after construction. Choose from the object's invariants and call-site clarity, not a fixed field count.
Code Example
import java.util.List;
// CONSTRUCTOR: best for 1-3 required fields, simple immutable value
record Point(int x, int y) {} // Java 17 record
// SETTERS (JavaBean): only for genuinely mutable entities (e.g. JPA)
class CartEntity {
private String status;
public void setStatus(String s){ this.status = s; } // mutable on purpose
public String getStatus(){ return status; }
}
// BUILDER: 4+ fields with several optional, want immutability
class OrderRequest {
private final Long customerId; private final List<String> items;
private final String coupon; private final boolean giftWrap;
private OrderRequest(Builder b){
customerId = b.customerId; items = b.items; coupon = b.coupon; giftWrap = b.giftWrap;
}
static class Builder {
private final Long customerId; private final List<String> items;
private String coupon; private boolean giftWrap;
Builder(Long c, List<String> i){ this.customerId = c; this.items = i; }
Builder coupon(String c){ this.coupon = c; return this; }
Builder giftWrap(boolean g){ this.giftWrap = g; return this; }
OrderRequest build(){ return new OrderRequest(this); }
}
}
Common Mistakes & Pitfalls
- Using Builder for every class: Freshers read that Builder is "best practice" and apply it universally, even to simple two-field value objects where a constructor is clearer and more idiomatic.
- Mixing constructors and setters without a strategy: Creating objects with partial constructors then calling setters to finish initialization leads to temporarily invalid states and thread-safety issues — commit to one construction approach.
- Using setters on immutable DTOs: Some freshers make all fields settable "just in case" on request DTOs, breaking immutability and allowing modification after validation.
- Not using records for simple immutable data: Java 17 records are perfect for simple immutable types with two to four required fields, but freshers often write full classes with constructors when a record is cleaner.
Check your understanding
Answer these without looking back at the article.
- Should JPA entities use Builder?
- Is it possible to have both a constructor and a Builder for the same class?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.