Lombok @Builder Annotation
Fast recall
Quick revision
Core answer
@Builder generates a builder type, fluent methods for the target parameters or fields, and a build() method during compilation. It removes handwritten builder boilerplate, but it does not by itself validate required fields, make the result immutable, copy mutable collections, or preserve field initializers unless @Builder.Default is used. Use it when that generated API matches the object's construction rules; be careful with JPA entities and other framework-managed types.Interview-ready guide
Interview answer
Lombok's @Builder generates the builder class, fluent input methods, and build() call at compile time for the annotated type, constructor, or method. It is useful when an object has several clearly named construction inputs and a generated builder expresses the API well. I do not treat it as automatic validation or immutability: omitted values can still be null or primitive defaults, field initializers need @Builder.Default if they should apply through the builder, and mutable collections need defensive copies. I also use care with JPA entities because their constructors, proxies, identity, and mutation lifecycle are framework concerns. DTOs and value objects are usually simpler candidates.
Lombok @Builder Annotation
Direct Answer
Lombok's @Builder generates a builder type, fluent methods for the target parameters or fields, and a build() method during compilation. It removes handwritten builder boilerplate, but it does not by itself validate required fields, make the result immutable, copy mutable collections, or preserve field initializers unless @Builder.Default is used. Use it when that generated API matches the object's construction rules; be careful with JPA entities and other framework-managed types.
Code Example
import lombok.Builder;
import lombok.Value;
import java.util.List;
@Value
@Builder
public class CartCheckoutRequest {
Long customerId;
List<String> itemIds;
String paymentMethod;
String discountCode;
boolean giftWrap;
String deliveryNotes;
}
// Usage in Spring controller
@RestController
public class CartController {
@PostMapping("/checkout")
public ResponseEntity<String> checkout() {
var request = CartCheckoutRequest.builder()
.customerId(12345L)
.itemIds(List.of("ITEM-001", "ITEM-002"))
.paymentMethod("CREDIT_CARD")
.discountCode("SAVE10")
.giftWrap(true)
.deliveryNotes("Leave at front door")
.build(); // Lombok generates this entire Builder
return ResponseEntity.ok("Order processed");
}
}
// With toBuilder for creating modified copies
@Builder(toBuilder = true)
public record OrderSummary(Long orderId, String status, Double total) {}
// Usage: create a modified copy
var original = OrderSummary.builder()
.orderId(100L).status("PENDING").total(99.99).build();
var updated = original.toBuilder()
.status("COMPLETED") // change just this field
.build(); // returns new immutable copy
Common Mistakes & Pitfalls
- Assuming validation is generated: omitted required values stay absent unless custom construction logic rejects them.
- Forgetting defaults: a field initializer is not a builder default unless
@Builder.Defaultis used deliberately. - Calling the result immutable:
@Builder, and even final references, do not protect mutable lists, arrays, or elements without copies. - Adding it blindly to an entity: check JPA constructor, proxy, identity, and relationship rules first.
- Depending on generated details accidentally: inspect delomboked output or the documented API when annotations interact.
Check your understanding
Answer these without looking back at the article.
- How do you set a default value for a field with Lombok @Builder?
- What is @Builder.Default in Lombok?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.