
当子类使用 Lombok @Builder 继承自带 @Builder 的父类时,生成的 Builder 不会自动包含父类字段(如 itemInfo),导致编译错误;解决方案是改用实验性注解 @SuperBuilder,它专为继承场景设计,能生成层级化、可组合的构建器。
当子类使用 lombok `@builder` 继承自带 `@builder` 的父类时,生成的 builder 不会自动包含父类字段(如 `iteminfo`),导致编译错误;解决方案是改用实验性注解 `@superbuilder`,它专为继承场景设计,能生成层级化、可组合的构建器。
Lombok 的标准 @Builder 注解不支持继承——即使 B extends A,B.Builder 也仅感知 B 自身声明的字段(bestPrice、alternativePrice),而不会识别或代理父类 A 中的 itemInfo。这是由 Lombok 的代码生成机制决定的:每个 @Builder 独立生成静态内部 Builder 类,不进行跨类字段合并。
✅ 正确做法:启用并使用 @SuperBuilder
@SuperBuilder 是 Lombok 提供的实验性功能(自 v1.18.2 起稳定可用),它通过为每个类生成带泛型参数的抽象构建器基类,并利用方法链式返回子类型,实现父子字段的无缝集成。
改造示例:
@Getter
@Setter
@ToString
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@SuperBuilder(toBuilder = true) // ✅ 替换为 @SuperBuilder
@EqualsAndHashCode
public class A {
private ItemInfo itemInfo;
public boolean hasErrors() {
return itemInfo != null && itemInfo.hasErrors();
}
}
@Getter
@Setter
@ToString
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@SuperBuilder(toBuilder = true) // ✅ 子类同样使用 @SuperBuilder
@EqualsAndHashCode(callSuper = true) // ⚠️ 注意:equals/hashCode 需显式包含父类
public class B extends A {
private Price bestPrice;
private Price alternativePrice;
}
✅ 此时,构建器可正常使用父类字段:
B mocked = B.builder()
.itemInfo(null) // ✅ 编译通过!来自 A 的字段
.bestPrice(null)
.alternativePrice(null)
.build();
? 启用说明(Maven):
确保 Lombok 版本 ≥ 1.18.2,并在 lombok.config 中启用(推荐):
# lombok.config lombok.anyConstructor.addConstructorProperties = true lombok.experimental.superBuilder = true # 启用 SuperBuilder 实验特性
⚠️ 注意事项:
-
@SuperBuilder要求所有参与继承链的类都标注该注解(包括父类A和子类B); -
@EqualsAndHashCode建议设置callSuper = true,否则子类equals()可能忽略父类字段; - 构造器访问级别(如
@AllArgsConstructor(access = AccessLevel.PACKAGE))仍生效,但@SuperBuilder会绕过构造器,直接设字段值; - 若项目禁用实验性特性,需在 IDE(如 IntelliJ)中启用 Lombok 插件的 “Enable experimental features” 选项。
? 总结:@Builder 是扁平化构建器,适用于独立类;@SuperBuilder 是面向继承的构建器方案——它是解决“子类 Builder 缺失父类字段”问题的标准、简洁且类型安全的答案。










