从抽象父类继承变量问题:Builder模式子类构造器异常
问题分析与解决方案
问题根源
Java中父类的private字段不会被子类继承,Lombok的@AllArgsConstructor仅会生成包含当前类自身声明字段的构造器。由于你的StringValidatorConfig没有自定义字段,所以实际生成的是无参构造器,导致build()方法中调用new StringValidatorConfig(false, false)报错。
方案一:使用Lombok @SuperBuilder(推荐)
@SuperBuilder是Lombok专门为继承场景设计的注解,能自动处理父类字段的初始化,无需手动编写大量Builder代码。
父类代码调整
@Getter @SuperBuilder public abstract class CommonValidatorConfig<VC extends CommonValidatorConfig<VC>> { protected boolean canBeNull; protected boolean canBeEmpty; public static abstract class CommonValidatorConfigBuilder<VC, VCB extends CommonValidatorConfigBuilder<VC, VCB>> { public VCB canBeNull(boolean canBeNull) { this.canBeNull = canBeNull; return (VCB) this; } public VCB canBeEmpty(boolean canBeEmpty) { this.canBeEmpty = canBeEmpty; return (VCB) this; } public VCB setDefault() { this.canBeNull = false; this.canBeEmpty = false; return (VCB) this; } public abstract VC build(); } }
子类代码调整
@SuperBuilder(builderMethodName = "builder") public class StringValidatorConfig extends CommonValidatorConfig<StringValidatorConfig> { // Lombok自动生成符合要求的Builder类,无需手动编写 }
使用示例
StringValidatorConfig config = StringValidatorConfig.builder() .canBeNull(true) .canBeEmpty(false) .build();
方案二:手动实现构造器与Builder
如果不想依赖@SuperBuilder,可以通过手动编写构造器和Builder来解决:
父类代码调整
@Getter public abstract class CommonValidatorConfig<VC extends CommonValidatorConfig<VC>> { private boolean canBeNull; private boolean canBeEmpty; // 提供protected构造器,供子类调用初始化父类字段 protected CommonValidatorConfig(boolean canBeNull, boolean canBeEmpty) { this.canBeNull = canBeNull; this.canBeEmpty = canBeEmpty; } public static abstract class CommonValidatorConfigBuilder<VC, VCB extends CommonValidatorConfigBuilder<VC, VCB>> { protected boolean canBeNull; protected boolean canBeEmpty; @SuppressWarnings("unchecked") public VCB canBeNull(boolean canBeNull) { this.canBeNull = canBeNull; return (VCB) this; } @SuppressWarnings("unchecked") public VCB canBeEmpty(boolean canBeEmpty) { this.canBeEmpty = canBeEmpty; return (VCB) this; } @SuppressWarnings("unchecked") public VCB setDefault() { this.canBeNull = false; this.canBeEmpty = false; return (VCB) this; } public abstract VC build(); } }
子类代码调整
public class StringValidatorConfig extends CommonValidatorConfig<StringValidatorConfig> { // 私有构造器,仅允许内部Builder调用 private StringValidatorConfig(boolean canBeNull, boolean canBeEmpty) { super(canBeNull, canBeEmpty); } public static class StringValidatorConfigBuilder extends CommonValidatorConfigBuilder<StringValidatorConfig, StringValidatorConfigBuilder> { @Override public StringValidatorConfig build() { return new StringValidatorConfig(this.canBeNull, this.canBeEmpty); } } // 对外提供Builder入口 public static StringValidatorConfigBuilder builder() { return new StringValidatorConfigBuilder().setDefault(); } }
代码优化建议
- 优先使用
@SuperBuilder:减少手动代码量,避免重复实现逻辑,同时保证类型安全。 - 父类字段权限调整:将父类需要被子类初始化的字段设为
protected,或者提供protected构造器,避免直接访问private字段。 - Builder泛型约束:保留父类Builder的泛型设计,确保链式调用返回正确的子类Builder实例,避免强制类型转换的风险。
内容的提问来源于stack exchange,提问作者Paul Marcelin Bejan
相关产品推荐
相关产品推荐

