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

从抽象父类继承变量问题: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();
    }
}

代码优化建议

  1. 优先使用@SuperBuilder:减少手动代码量,避免重复实现逻辑,同时保证类型安全。
  2. 父类字段权限调整:将父类需要被子类初始化的字段设为protected,或者提供protected构造器,避免直接访问private字段。
  3. Builder泛型约束:保留父类Builder的泛型设计,确保链式调用返回正确的子类Builder实例,避免强制类型转换的风险。

内容的提问来源于stack exchange,提问作者Paul Marcelin Bejan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:15:30