有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在带有最终字段的抽象类上使用Lombok@SuperBuilder

给定以下带有Lombok注释的类@Data@SuperBuilder

@Data
@SuperBuilder
public abstract class Parent {

    protected final String userId;
    protected final Instant requestingTime;
}

@Data
@SuperBuilder
public class Child extends Parent {

    private final Instant beginningDate;
    private final Instant endingDate;
    private final Collection<String> fields;
}

Child类中的@Data注释上出现以下错误:

Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor.

有没有办法在Child类的@Data注释上配置非默认构造函数,以便在调用生成器时初始化ChildParent类上的所有final字段

我在子类和父类上尝试了@Data@Getter@Setter注释与@SuperBuilder注释的几种不同组合,但尚未找到有效的解决方案。我正在使用Lombok 1.18.10

作为参考,this问题是相关的

编辑

这实际上是Lombok应该在SuperBuilder.build()操作上构造和调用的构造函数

public Child(
    final String userId,
    final Instant requestingTime,
    final Instant beginningDate,
    final Instant endingDate,
    final Collection<String> fields) {

    super(userId, requestingTime);
    this.beginningDate = beginningDate;
    this.endingDate = endingDate;
    this.fields= fields;
}

根据请求,这就是我希望在Child对象上调用生成器的方式

final Child child = Child.Builder()
                         .userId(<value>)
                         .requestingTime(<value>)
                         .beginningDate(<value>)
                         .endingDate(<value>)
                         .fields(<value>)
                         .build();

共 (2) 个答案

  1. # 1 楼答案

    @Data annotation隐式生成以下功能的代码:


    • 塞特
    • 吸气剂
    • 托斯特林
    • equallAndHashCode
    • 构造函数(仅适用于必需参数)

    这意味着loombok的构造函数声明将生成父类的代码,如下所述:

    个人(字符串用户ID,即时请求时间)

    类似地,儿童班:

    子项(即时开始日期、即时结束日期、集合字段)


    现在,当您的程序抛出异常时

    Parent() is undefined in parent class.

    请在课堂上注明:

    @NoArgsConstructor

    这将生成所需的默认构造函数

  2. # 2 楼答案

    最后,@Data生成一个@NoArgsConstructor,这是错误的。实际上,@Data本身是错误的,因为它是针对可变类的@Value会更好,但它也不能处理超级构造函数

    因此,删除@Data,添加@Getter@EqualsAndHashCode@ToString以及您需要的任何内容。别忘了在子类中添加callSuper=true


    This is effectively the constructor that Lombok should be constructing and invoking on the SuperBuilder.build() operation.

    public Child(
        final String userId,
        final Instant requestingTime,
        final Instant beginningDate,
        final Instant endingDate,
        final Collection<String> fields) {
    
        super(userId, requestingTime);
        this.beginningDate = beginningDate;
        this.endingDate = endingDate;
        this.fields= fields;
    }
    

    不,那不是SuperBuilder的工作方式。这实际上是龙目山不能做的,因为它看不到超视场。相反,构建器使用

    public Child(ChildBuilder b) {    
        super(b);
        this.beginningDate = b.beginningDate;
        this.endingDate = b.endingDate;
        this.fields= b.fields;
    }
    

    你可以相信Jan Rieke说的话,他写的