Free tools Windows power users keep installed
One-click scans. No signup required.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To use Lombok @Builder with inheritance in Java, use @SuperBuilder on every class in the hierarchy. Plain @Builder does not automatically add superclass fields to a subclass builder, while @SuperBuilder lets one fluent builder set both inherited and subclass fields.
This distinction matters because Java inheritance and builder inheritance are separate concerns. A subclass can inherit object members without its generated builder inheriting the parent builder’s methods.
Key takeaways
@SuperBuilderis Lombok’s inheritance-aware builder feature, and every class in the participating hierarchy must use it.- Plain
@Builderdoes not automatically combine superclass fields with subclass fields, although@Builderon a constructor can manually expose both. @SuperBuilderis documented as experimental and was introduced in Lombok 1.18.2.toBuilder = truemust be enabled throughout the hierarchy, and the resulting copy operation is not automatically a deep clone.- For JDK 23 and later, Lombok’s Maven documentation requires explicit annotation-processor configuration; modular JDK 9+ builds also require processor configuration.
Why does plain Lombok @Builder not handle inheritance automatically?
Plain Lombok @Builder generates a builder from the fields of the annotated type or from the parameters of an annotated constructor or method. Plain @Builder does not automatically merge superclass state into a child-class builder, as documented in Lombok’s @Builder reference.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFor example, this looks plausible but does not create a single inheritance-aware builder:
import lombok.Builder;
@Builder
class Vehicle {
private String manufacturer;
}
@Builder
class Car extends Vehicle {
private int numberOfDoors;
}
The generated Car.builder() is based on Car’s own builder target. The child builder should not be expected to expose manufacturer(...) merely because Car extends Vehicle.
The important distinction is:
- Object inheritance: a subclass receives accessible members from its superclass.
- Builder inheritance: generated builder types must be connected so that parent fields remain available while constructing the child.
Use Lombok’s @SuperBuilder when the desired API is one fluent builder spanning the hierarchy.
What is the correct way to use Lombok @Builder with inheritance?
The Lombok-supported solution for an inheritance-aware builder is @SuperBuilder on every class in the hierarchy. The child builder then exposes methods for both superclass and subclass fields.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →import lombok.Getter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
@Getter
@ToString
@SuperBuilder
public class Person {
private final String name;
}
@Getter
@ToString(callSuper = true)
@SuperBuilder
public class Employee extends Person {
private final String employeeId;
}
Construct an Employee with both fields through the child builder:
Employee employee = Employee.builder()
.name("Ada Lovelace")
.employeeId("E-100")
.build();
System.out.println(employee.getName());
System.out.println(employee.getEmployeeId());
The generated child builder participates in the same builder hierarchy as the parent builder. Lombok documents this design in the @SuperBuilder feature documentation and its @SuperBuilder API documentation.
What does a multi-level inheritance builder look like?
Every intermediate class counts: a base class, abstract class, and concrete subclass must all use compatible @SuperBuilder configuration.
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
public class Vehicle {
private final String manufacturer;
}
@Getter
@SuperBuilder
public class SportsCar extends Vehicle {
private final String model;
}
@Getter
@SuperBuilder
public class TrackCar extends SportsCar {
private final int topSpeed;
}
TrackCar car = TrackCar.builder()
.manufacturer("Porsche")
.model("911")
.topSpeed(320)
.build();
The TrackCar builder can set the manufacturer declared by Vehicle, the model declared by SportsCar, and the speed declared by TrackCar. Omitting @SuperBuilder from SportsCar breaks the complete builder chain.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →What is the difference between @Builder and @SuperBuilder?
@Builder is suitable for a single construction target, while @SuperBuilder is intended for builder APIs that span an inheritance hierarchy.
| Concern | @Builder |
@SuperBuilder |
|---|---|---|
| Superclass fields in a child builder | Not automatic | Supported through the builder hierarchy |
| Annotation target | Type, constructor, or method | Classes participating in the hierarchy |
| Hierarchy requirement | Does not create an inherited builder chain | Every class in the hierarchy must use @SuperBuilder |
| Compatibility | Use for a standalone builder or a manually selected constructor | Not compatible with @Builder in the same inheritance chain |
| Project status | Main Lombok builder feature | Documented by Lombok as experimental |
Lombok explicitly states that all classes in the hierarchy must be annotated with @SuperBuilder and that @SuperBuilder is not compatible with @Builder for this purpose. Treat @SuperBuilder as the intended Lombok solution, not as a universal replacement for every builder design.
Is @SuperBuilder experimental?
Yes. Lombok documents @SuperBuilder under its experimental features, although the feature is specifically designed for classes that extend one another. Lombok records that @SuperBuilder was introduced in version 1.18.2; check the official feature page when evaluating project policy.
Experimental status is primarily a governance consideration. Teams with strict dependency, generated-code, or public-API policies should review the generated API and decide whether Lombok’s approach is acceptable for the project.
Recommended Free Tools
How do you configure Lombok in Maven?
A Maven project needs Lombok as a compile-time dependency, and annotation processing must be available to the compiler. The official Lombok Maven setup page currently uses version 1.18.46 in its example; verify the version against the JDK supported by your project rather than treating that example as permanently current.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.46</version>
<scope>provided</scope>
</dependency>
For JDK 23 and later, Lombok’s current Maven setup documentation says explicit annotation-processor configuration is mandatory. The same documentation calls out JDK 9 and later when compiling as modules with module-info.java.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.46</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
The Lombok artifact is also available through Maven Central. A clean build is useful after changing the Lombok version or processor configuration because stale generated classes can hide configuration problems.
How do you configure Lombok in Gradle?
Gradle requires Lombok on the compile-only and annotation-processor configurations. Keep the dependency versions synchronized with the JDK and Lombok release policy used by the project.
dependencies {
compileOnly "org.projectlombok:lombok:1.18.46"
annotationProcessor "org.projectlombok:lombok:1.18.46"
testCompileOnly "org.projectlombok:lombok:1.18.46"
testAnnotationProcessor "org.projectlombok:lombok:1.18.46"
}
The exact version should be selected for the project’s supported toolchain. If the IDE compiles successfully but Gradle or CI fails, compare the IDE’s annotation-processing setup with the Gradle processor configuration.
Can an abstract base class use @SuperBuilder?
Yes. An abstract base class can participate in the generated builder hierarchy without being instantiated; the concrete subclass provides the usable builder() entry point.
import lombok.Getter;
import lombok.experimental.SuperBuilder;
@Getter
@SuperBuilder
public abstract class Message {
private final String messageId;
}
@Getter
@SuperBuilder
public class EmailMessage extends Message {
private final String recipient;
}
EmailMessage message = EmailMessage.builder()
.messageId("msg-1")
.recipient("ada@example.com")
.build();
The abstract base class and every intermediate class must use compatible @SuperBuilder settings. The base class does not need a public builder entry point if only concrete subclasses are constructed.
How do you use toBuilder with inherited fields?
Enable toBuilder = true on every class in the hierarchy, then create a new object by changing selected builder values.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
import lombok.experimental.SuperBuilder;
@SuperBuilder(toBuilder = true)
class Vehicle {
private final String manufacturer;
}
@SuperBuilder(toBuilder = true)
class Car extends Vehicle {
private final int numberOfDoors;
}
Car original = Car.builder()
.manufacturer("Toyota")
.numberOfDoors(4)
.build();
Car modified = original.toBuilder()
.numberOfDoors(2)
.build();
Lombok requires toBuilder = true throughout the hierarchy. The operation initializes a builder from the existing object’s values; it is a shallow value-copy mechanism, not an automatic deep clone. Nested objects and collections retain whatever copy or mutability behavior their own types provide. See Lombok’s @SuperBuilder documentation for the hierarchy-wide requirement.
How do inherited collections work with @Singular?
@Singular generates collection-oriented builder methods, including an element-at-a-time method, and those methods remain available through a @SuperBuilder hierarchy.
import java.util.List;
import lombok.Singular;
import lombok.experimental.SuperBuilder;
@SuperBuilder
public class Order {
@Singular
private final List<String> tags;
}
@SuperBuilder
public class OnlineOrder extends Order {
private final String trackingNumber;
}
OnlineOrder order = OnlineOrder.builder()
.tag("priority")
.tag("gift")
.trackingNumber("TRACK-123")
.build();
Test the generated method name for the collection and naming convention used by the project. Lombok may not infer the desired singular form for irregular, unusual, or non-English plurals; an explicit singular form may be needed. Also document whether the resulting collection should be treated as immutable or defensively copied rather than assuming that the builder annotation alone defines the application’s collection policy. Lombok describes @Singular support in its builder documentation.
How should defaults and validation be handled?
Builder defaults and domain validation are separate concerns. A field initializer is not necessarily used when a generated builder creates an object, so use @Builder.Default when the initializer is intended to be the builder’s default.
import lombok.Builder;
import lombok.experimental.SuperBuilder;
@SuperBuilder
public class Account {
@Builder.Default
private final boolean active = true;
}
Verify default behavior with the Lombok version used by the project, especially when combining defaults with explicit constructors or other Lombok annotations.
For a required reference, @NonNull can cause a generated null check for recognized nullity annotations:
import lombok.NonNull;
import lombok.experimental.SuperBuilder;
@SuperBuilder
public class Customer {
@NonNull
private final String customerId;
}
A generated null check is not a complete domain-validation strategy. Blank strings, invalid ranges, cross-field rules, authorization conditions, and other invariants still need validation in a constructor, build path, or explicit domain service.
What happens when you add a custom constructor?
@SuperBuilder generates a protected constructor that accepts a generated builder instance and initializes the object from builder state. Explicit constructors and constructor annotations can change what Lombok is able to generate, so constructor-heavy classes require extra care.
For advanced invariant enforcement, validation can be placed in a protected builder-based constructor:
import lombok.experimental.SuperBuilder;
@SuperBuilder
public class Product {
private final String sku;
protected Product(ProductBuilder<?, ?> builder) {
this.sku = builder.sku;
if (sku == null || sku.isBlank()) {
throw new IllegalArgumentException("sku must not be blank");
}
}
}
The generated builder generic signature can be complex, and the exact generated type must match the Lombok version and class configuration. Inspect delomboked output before customizing a @SuperBuilder constructor. Lombok documents the protected builder-based constructor and customization guidance in the @SuperBuilder feature documentation.
Do not assume that adding @NoArgsConstructor, a framework constructor, or a custom constructor is harmless. Framework requirements such as a no-argument constructor, visibility, mutability, proxies, or deserialization may need a separate design from the builder API.
Rank #4
How do you inspect the generated builder?
Use delomboked source when the generated builder’s generic types, constructors, or customization points are difficult to understand. Lombok recommends delomboked code as a reference when customizing @SuperBuilder.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minute- Confirm that annotation processing is enabled.
- Compile the smallest possible parent-and-child example.
- Read the compiler error before changing annotations.
- Delombok the classes and inspect the generated builder types.
- Check whether the child builder extends the expected parent builder.
- Check that parent and child builder configuration matches.
- Remove customizations until the basic hierarchy compiles.
- Reintroduce custom code one change at a time.
The Lombok Maven setup documentation also covers the Lombok Maven plugin and delomboking use cases such as source analysis and Javadoc generation.
How do you troubleshoot a missing inherited builder method?
When Child.builder() lacks a parent setter such as manufacturer(...), first verify that the parent, child, and every intermediate superclass use @SuperBuilder.
| Observed problem | Likely cause | First action |
|---|---|---|
Parent field is missing from Child.builder() |
Parent or intermediate class uses @Builder, or annotation processing is disabled |
Use @SuperBuilder throughout the hierarchy and check compiler processing |
@Builder and @SuperBuilder conflict |
The annotations are mixed in one inheritance chain | Choose one strategy; use @SuperBuilder for the whole chain |
builder() is missing entirely |
Lombok is not being processed, the dependency is absent, or generated classes are stale | Check the dependency, processor path, IDE settings, and perform a clean build |
toBuilder() is missing |
toBuilder = true is absent from one hierarchy level |
Enable it on every participating class |
| Custom builder does not compile | Generic parameters, builder names, return types, or generated members collide | Compare custom code with delomboked output and restore the default configuration |
| IDE succeeds but CI fails | Different JDK, Lombok version, processor path, or clean-build behavior | Compare toolchains and explicitly configure annotation processing |
Lombok’s @SuperBuilder documentation notes that the generated implementation relies heavily on generics to preserve type safety and avoid casts. Intimidating generated signatures are therefore expected; delombok is safer than recreating them from memory.
Custom builder names require another hierarchy-wide check. Lombok’s builder-class-name configuration must be consistent across all @SuperBuilder classes. A mismatch can produce incompatible builder types even when the ordinary field annotations look correct.
Can Jackson use a Lombok @SuperBuilder?
Jackson integration should be evaluated separately from builder inheritance. Lombok points to @Jacksonized for Jackson integration with Lombok builders, but the exact annotations and framework requirements depend on the project’s Jackson and Lombok versions.
A builder does not automatically satisfy requirements imposed by JPA, serialization libraries, dependency-injection frameworks, or proxy mechanisms. If a framework requires a no-argument constructor, particular visibility, setters, or mutable state, provide and test those requirements independently of the fluent builder.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.When should you avoid @SuperBuilder?
@SuperBuilder is usually the most direct Lombok choice when the parent and child classes are under your control and a fluent builder must set inherited fields. Other designs are reasonable when generated inheritance code conflicts with ownership, validation, or API requirements.
| Situation | Preferred approach | Trade-off |
|---|---|---|
| Parent and child are both under your control | @SuperBuilder |
Direct Lombok solution, but the entire hierarchy participates in generated code |
| Parent cannot be modified | Child constructor with @Builder |
Works, but the child repeats every parent constructor parameter |
| Hierarchy is shallow with few fields | Manual constructor builder | Less generated complexity, more explicit maintenance |
| Construction has branching or complex invariants | Handwritten builder | More code, but precise control over build-time rules |
| Shared fields do not represent polymorphism | Composition | Simpler builder API, but a different domain model |
| Public library API has strict generated-code rules | Handwritten or deliberately selected builder design | Stable and explicit API, with greater implementation effort |
How can a child constructor use plain @Builder as an alternative?
Because Lombok @Builder can target a constructor or method, a child constructor can accept both parent and child values and expose those constructor parameters through one builder.
import lombok.Builder;
import lombok.Getter;
@Getter
public class Car extends Vehicle {
private final int numberOfDoors;
@Builder
public Car(String manufacturer, int numberOfDoors) {
super(manufacturer);
this.numberOfDoors = numberOfDoors;
}
}
Car car = Car.builder()
.manufacturer("Toyota")
.numberOfDoors(4)
.build();
This works because the builder is generated from the constructor parameter list, not because Lombok inferred builder inheritance. The approach is useful for a shallow hierarchy or when the parent class cannot be changed.
Best Value
The cost is repeated coupling: every subclass must maintain a complete constructor parameter list, and a parent-field change may require edits in multiple child constructors. The constructor- and method-target behavior is described in Lombok’s @Builder documentation.
Should you use composition or a handwritten builder instead?
Use composition when the apparent hierarchy only exists to reuse data and polymorphic substitution is not required.
import lombok.Builder;
@Builder
public class Car {
private VehicleDetails vehicle;
private int numberOfDoors;
}
Use a handwritten builder when construction includes complex validation, staged construction, branching, a public API whose method names must remain stable, a project that avoids annotation processors, or generated generic types that maintainers cannot reasonably own.
Other code-generation libraries can also be considered, but their suitability depends on mutability, Java version, annotation-processing policy, generated-code ownership, and interoperability. A different library should be selected from project requirements rather than assumed to be superior.
Recommended implementation checklist
- Decide whether the hierarchy represents genuine polymorphism. If it only shares data, compare composition first.
- Annotate the parent, every intermediate class, and the child with
@SuperBuilder. - Remove
@Builderfrom the same inheritance chain. - Confirm Lombok is available to the compiler and annotation processing is enabled.
- For JDK 23+ or modular builds, configure the annotation processor explicitly.
- Compile a minimal call that sets one parent field and one child field.
- Add
toBuilder = trueto every hierarchy level if cloning-and-modifying is required. - Review defaults, null checks, collection behavior, constructors, and framework requirements separately.
- Use delomboked output before customizing builder classes or protected constructors.
- Run a clean command-line build in addition to the IDE build.
Frequently Asked Questions
Can I put Lombok @Builder on both a parent and child class?
Putting plain Lombok @Builder on both classes does not create one builder containing inherited fields. Use @SuperBuilder throughout the hierarchy, or put @Builder on a child constructor that explicitly accepts the parent values.
Does every class in a Lombok @SuperBuilder hierarchy need the annotation?
Yes. Lombok requires every class in the participating inheritance hierarchy, including abstract and intermediate classes, to use @SuperBuilder with compatible configuration.
Why is the superclass field missing from Child.builder()?
The usual causes are a parent or intermediate class using @Builder, disabled annotation processing, stale generated classes, or inconsistent custom builder configuration. Start with a clean build and verify @SuperBuilder on every hierarchy level.
Does Lombok toBuilder create a deep copy?
No. toBuilder() initializes a builder with the existing object’s values. Nested objects and collections are not automatically deep-copied.
Is Lombok @SuperBuilder stable?
Lombok documents @SuperBuilder as experimental. It is specifically intended for inheritance, but teams with strict dependency or generated-code policies should review the generated API before adopting it.
The Bottom Line
For a Lombok builder that sets both superclass and subclass fields, annotate every class in the hierarchy with @SuperBuilder and do not mix it with @Builder. Use a constructor-targeted @Builder, composition, or a handwritten builder when the parent cannot change or construction rules require more explicit control.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

