You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承场景下Lombok @With注解报错无法正常使用如何解决

目前Lombok的@With注解原生不支持继承场景下自动识别父类字段生成符合要求的with方法,不过可以通过@SuperBuilder搭配极简的手写with逻辑实现相同效果,代码改动量极小。

解决步骤

  1. 给父类Order添加@SuperBuilder(toBuilder = true)注解,开启支持继承的Builder能力,且允许从已有实例复制属性生成Builder
@EqualsAndHashCode(callSuper = true)
@Getter
@SuperBuilder(toBuilder = true) // 新增注解
public abstract class Order extends SelfValidating<Order> {
  // 原有代码不变
  @Valid
  @NotBlank(message = "orderNumber must not be empty")
  private final String orderNumber;
  private final String orderId;
  private final String externalOrderId;

  protected Order(String orderNumber, String orderId, String externalOrderId) {
    this.orderNumber = orderNumber;
    this.orderId = orderId;
    this.externalOrderId = externalOrderId;
  }
}
  1. 子类ChildOrder移除属性上的@With注解,换成类上添加@SuperBuilder(toBuilder = true),替换原有@Builder注解
@EqualsAndHashCode(callSuper = true)
@Value
@SuperBuilder(toBuilder = true) // 替换原来的@Builder
public class ChildOrder extends Order {

  @NotBlank(message = "Invoice number should not be blank")
  @Valid
  String invoiceNumber;

  public ChildOrder(
      String orderNumber,
      String orderId,
      String externalOrderId,
      String invoiceNumber) {
    super(orderNumber, orderId, externalOrderId);
    this.invoiceNumber = invoiceNumber;
    super.validateSelf();
  }

  // 手写极简with方法
  public ChildOrder withInvoiceNumber(String invoiceNumber) {
    return this.toBuilder().invoiceNumber(invoiceNumber).build();
  }
}

方案说明

  • 该方案完全保留了不可变类的特性,新生成的对象和原有对象互不影响
  • 不需要手动复制父类的三个属性,toBuilder()会自动完成所有属性的复制,只需要修改指定字段即可
  • 构建新对象时依然会调用你自定义的全参构造,原有validateSelf()校验逻辑不会丢失
  • 如果后续有其他需要支持with的字段,只需要新增对应一行的with方法即可,不需要额外配置

注意:需要使用1.18.22及以上版本的Lombok才能正常使用@SuperBuilder的toBuilder能力。

内容的提问来源于stack exchange,提问作者Ramon Paris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 01:54:05