如何在子类Builder中使用父类的默认值
问题:子类Builder无法继承父类@Default注解的默认值
现有代码
1. BaseCustomer.java
@NoArgsConstructor @AllArgsConstructor @Getter @Builder(builderMethodName="BaseBuilder") public class BaseCusmtomer { private String cutomerId; private String age; @Default private Boolean isActive= true; @Default private String type = "XYZ"; }
2. Customer.java
@Builder public class Customer extends BaseCustomer{ private Customer(String cutomerId, String age, Boolean isActive, String type){ super(customerId,age,isActive,type); } }
3. 测试代码
Customer.builder().cutomerId("1").age("23").build();
问题现象
使用Customer.builder()创建对象时,父类中标记了@Default的isActive和type字段始终为null,无法继承父类设定的默认值(预期isActive=true,type="XYZ")。尝试通过子类Builder调用父类默认值无效,且不能使用@SuperBuilder(因为是实验性功能)。
这是因为Lombok的@Builder注解仅作用于当前类,不会自动识别并继承父类中@Default标记的字段默认值,子类Builder未给这些字段赋值时会传入null,导致父类构造器接收的是null而非预设的默认值。
解决方案
方案1:在子类构造器中补全默认值逻辑
直接在子类的构造方法中判断,如果父类字段传入的是null,则使用父类的默认值:
@Builder public class Customer extends BaseCustomer { private Customer(String customerId, String age, Boolean isActive, String type) { // 手动处理默认值:如果参数为null,使用父类的默认值 super( customerId, age, isActive != null ? isActive : true, type != null ? type : "XYZ" ); } }
方案2:复用父类Builder初始化
在子类中自定义Builder,复用父类的BaseBuilder来继承默认值逻辑,同时保留子类的扩展能力:
@Getter public class Customer extends BaseCustomer { // 自定义子类Builder public static class CustomerBuilder { // 复用父类的Builder来继承默认值 private BaseCustomer.BaseBuilder baseBuilder = BaseCustomer.BaseBuilder(); // 映射父类字段的Builder方法 public CustomerBuilder customerId(String customerId) { baseBuilder.cutomerId(customerId); return this; } public CustomerBuilder age(String age) { baseBuilder.age(age); return this; } // 提供覆盖父类默认值的方法 public CustomerBuilder isActive(Boolean isActive) { baseBuilder.isActive(isActive); return this; } public CustomerBuilder type(String type) { baseBuilder.type(type); return this; } // 构建方法:先通过父类Builder得到父类实例,再初始化子类 public Customer build() { BaseCustomer base = baseBuilder.build(); return new Customer( base.getCutomerId(), base.getAge(), base.getIsActive(), base.getType() ); } } // 对外暴露子类Builder入口 public static CustomerBuilder builder() { return new CustomerBuilder(); } private Customer(String customerId, String age, Boolean isActive, String type) { super(customerId, age, isActive, type); } }
以上两种方案都能让测试代码创建的对象自动继承父类的isActive=true和type="XYZ"默认值,同时满足不能使用@SuperBuilder的限制。
内容的提问来源于stack exchange,提问作者Harshad k
相关产品推荐
相关产品推荐

