如何强制子类初始化抽象父类属性且无需手动编写构造器?
解决方案
要实现强制子类填充surrogateId且避免手动编写构造器,可通过调整Lombok注解组合来实现,核心思路是利用final字段的强制初始化特性,配合Lombok的注解自动生成构造器或Builder:
方案一:@RequiredArgsConstructor + @AllArgsConstructor组合
调整父类
Report:- 将
surrogateId设为final,确保必须初始化 - 移除
@NoArgsConstructor(无参构造会导致final字段无法初始化,与强制要求冲突) - 保留
@Data,新增@RequiredArgsConstructor(Lombok会自动生成包含所有final/NonNull字段的构造器)
代码示例:
@Data @RequiredArgsConstructor public abstract class Report { private final String surrogateId; }- 将
子类配置:
- 保留
@Data、@Document注解 - 添加
@AllArgsConstructor:Lombok会生成包含父类final字段+子类所有字段的构造器,自动调用父类的构造器,无需手动编写 - 若子类无额外必填字段,也可使用
@RequiredArgsConstructor,效果一致
代码示例:
@Data @Document @AllArgsConstructor public class ReportActiveDevicesNotLinkedWithIO extends Report { // 子类自定义字段 private String deviceId; }此时如果子类未通过构造器传入
surrogateId,编译会直接报错,满足强制填充的要求。- 保留
方案二:使用@SuperBuilder实现Builder模式
如果更倾向于Builder风格的实例创建,可使用Lombok的@SuperBuilder:
父类配置:
@Data @SuperBuilder public abstract class Report { private final String surrogateId; }子类配置:
@Data @Document @SuperBuilder public class ReportActiveDevicesNotLinkedWithIO extends Report { private String deviceId; }创建实例时必须通过
builder().surrogateId("xxx")设置该字段,否则编译报错,完全无需手动编写构造器,同时保证surrogateId被强制填充。
关键注意点
- 必须移除父类的
@NoArgsConstructor:无参构造会绕过final字段的初始化检查,违背强制填充的需求 - 两种方案均无需手动编写任何构造器,所有构造逻辑由Lombok自动生成
内容的提问来源于stack exchange,提问作者Moussa ELaQ
相关产品推荐
相关产品推荐

