继承场景下Lombok @With注解报错无法正常使用如何解决
目前Lombok的@With注解原生不支持继承场景下自动识别父类字段生成符合要求的with方法,不过可以通过@SuperBuilder搭配极简的手写with逻辑实现相同效果,代码改动量极小。
解决步骤
- 给父类
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; } }
- 子类
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
相关产品推荐
相关产品推荐

