使用Lombok Builder创建带继承字段的实例时父类字段不可见如何解决
问题根因
Lombok 原生 @Builder 注解默认只会处理当前类定义的字段,无法识别继承自父类的属性,同时你当前临时使用的强转方案存在严重问题:AbstractCommentEvent 是抽象类,调用其 Builder 的 build() 方法生成的是 Lombok 自动创建的匿名实现类实例,强转为 CommentDeleteEvent 会直接抛出 ClassCastException,完全不可用。
最优解决方案
使用 Lombok 1.18.2 及以上版本提供的 @SuperBuilder 注解,该注解专门适配类继承场景,可让子类 Builder 直接访问父类的所有字段。
步骤1:修改父子类的 Builder 注解
将两个类上的 @Builder 全部替换为 @SuperBuilder:
// 父类AbstractCommentEvent修改后 @EqualsAndHashCode(callSuper = true) @Data @SuperBuilder // 替换原有的@Builder @ToString @AllArgsConstructor @NoArgsConstructor public abstract class AbstractCommentEvent extends AbstractEvent { private CommentDTO comment; public AbstractCommentEvent(EventType eventType, CommentDTO comment) { super(eventType); this.comment = comment; } }
// 子类CommentDeleteEvent修改后 @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @NoArgsConstructor @SuperBuilder // 替换原有的@Builder @Data public class CommentDeleteEvent extends AbstractCommentEvent { public CommentDeleteEvent(CommentDTO comment) { super(DELETE, comment); } }
步骤2:修改对象创建逻辑
直接使用子类 Builder 构造对象,无需强转,可直接访问父类字段:
public void sendDeletedEvent(final Comment comment) { log.info("SendDeletedEvent.E with Comment: {}", comment); final CommentDTO commentDTO = commentMapper.toDTO(comment); final CommentDeleteEvent commentDeleteEvent = CommentDeleteEvent.builder() .eventType(EventType.DELETE) .comment(commentDTO) .build(); kafkaTemplate.send(commentEventTopic, commentDeleteEvent); log.info("SendDeleteEvent.X with CommentDeleteEvent : {}", commentDeleteEvent); }
兼容方案(Lombok版本低于1.18.2时使用)
如果无法升级Lombok版本,可手动在子类中补充自定义Builder逻辑,不过该方案维护成本较高,仅作为临时兼容使用:
// 子类CommentDeleteEvent手动补充Builder方法 public static CommentDeleteEventBuilder builder(CommentDTO comment) { CommentDeleteEvent event = new CommentDeleteEvent(comment); return event.new CommentDeleteEventBuilder(); }
内容的提问来源于stack exchange,提问作者Олександр Житарюк
相关产品推荐
相关产品推荐

