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

如何强制子类初始化抽象父类属性且无需手动编写构造器?

解决方案

要实现强制子类填充surrogateId且避免手动编写构造器,可通过调整Lombok注解组合来实现,核心思路是利用final字段的强制初始化特性,配合Lombok的注解自动生成构造器或Builder:

方案一:@RequiredArgsConstructor + @AllArgsConstructor组合

  1. 调整父类Report:

    • 将surrogateId设为final,确保必须初始化
    • 移除@NoArgsConstructor(无参构造会导致final字段无法初始化,与强制要求冲突)
    • 保留@Data,新增@RequiredArgsConstructor(Lombok会自动生成包含所有final/NonNull字段的构造器)

    代码示例:

    @Data
    @RequiredArgsConstructor
    public abstract class Report {
        private final String surrogateId;
    }
    
  2. 子类配置:

    • 保留@Data、@Document注解
    • 添加@AllArgsConstructor:Lombok会生成包含父类final字段+子类所有字段的构造器,自动调用父类的构造器,无需手动编写
    • 若子类无额外必填字段,也可使用@RequiredArgsConstructor,效果一致

    代码示例:

    @Data
    @Document
    @AllArgsConstructor
    public class ReportActiveDevicesNotLinkedWithIO extends Report {
        // 子类自定义字段
        private String deviceId;
    }
    

    此时如果子类未通过构造器传入surrogateId,编译会直接报错,满足强制填充的要求。

方案二:使用@SuperBuilder实现Builder模式

如果更倾向于Builder风格的实例创建,可使用Lombok的@SuperBuilder:

  1. 父类配置:

    @Data
    @SuperBuilder
    public abstract class Report {
        private final String surrogateId;
    }
    
  2. 子类配置:

    @Data
    @Document
    @SuperBuilder
    public class ReportActiveDevicesNotLinkedWithIO extends Report {
        private String deviceId;
    }
    

    创建实例时必须通过builder().surrogateId("xxx")设置该字段,否则编译报错,完全无需手动编写构造器,同时保证surrogateId被强制填充。

关键注意点

  • 必须移除父类的@NoArgsConstructor:无参构造会绕过final字段的初始化检查,违背强制填充的需求
  • 两种方案均无需手动编写任何构造器,所有构造逻辑由Lombok自动生成

内容的提问来源于stack exchange,提问作者Moussa ELaQ

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:01:08