
当子类继承使用 @Builder 的父类时,Lombok 默认不会为子类 Builder 自动生成父类字段的 setter 方法(如 itemInfo()),导致编译错误;需改用 @SuperBuilder 实验性注解实现安全的继承式构建器。
当子类继承使用 `@builder` 的父类时,lombok 默认不会为子类 builder 自动生成父类字段的 setter 方法(如 `iteminfo()`),导致编译错误;需改用 `@superbuilder` 实验性注解实现安全的继承式构建器。
Lombok 的 @Builder 注解默认是“非继承感知”的:它只为标注类自身声明的字段生成构建方法,不会自动将父类字段纳入子类的 Builder 中。因此,尽管 B extends A 在运行时能访问 itemInfo,但 B.builder().itemInfo(...) 会编译失败——因为 BBuilder 类中根本不存在 itemInfo() 方法。
✅ 正确解决方案:使用 @SuperBuilder(需启用 Lombok 实验特性)
首先确保 Lombok 版本 ≥ 1.18.20,并在项目中启用实验性功能(如通过 lombok.config 或 IDE 设置)。然后重写类如下:
@Getter
@Setter
@ToString
@NoArgsConstructor(access = AccessLevel.PUBLIC)
@AllArgsConstructor(access = AccessLevel.PACKAGE)
@SuperBuilder(toBuilder = true) // ✅ 替换 @Builder
@EqualsAndHashCode(callSuper = true) // 注意:显式声明继承 equals/hashCode 行为
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)
public class B extends A {
private Price bestPrice;
private Price alternativePrice;
}此时,B.builder() 将自动包含 itemInfo()、bestPrice() 和 alternativePrice() 等所有可构建字段的方法,且类型安全、支持链式调用:
B mocked = B.builder()
.itemInfo(null) // ✅ 现在合法
.bestPrice(null)
.alternativePrice(null)
.build();⚠️ 注意事项:
-
@SuperBuilder生成的是泛型化、分层的构建器类(如A.ABuilder和B.BBuilder),子类构建器会委托父类构建逻辑,确保字段初始化顺序与继承链一致; - 必须为父类和子类同时启用
@SuperBuilder,仅一方使用无效; -
@EqualsAndHashCode和@ToString建议添加callSuper = true,以正确包含父类字段; - 若使用
toBuilder = true,则B实例的toBuilder()方法也能正确还原itemInfo等继承字段的值。
? 总结:@Builder 不支持继承,@SuperBuilder 是 Lombok 官方提供的、专为继承场景设计的替代方案。虽然标记为 experimental,但在主流版本中已稳定可用,是解决此类问题的标准实践。

















