Lombok中构造器的继承

38

我想在我的项目中使用lombok。

我有一个A类:

@Data
@Builder
public class A {
    Integer a1;
}

和一个类B:

@Data
public class B extends A {
    Integer b1;

    @Builder
    public B(Integer b1, Integer a1) {
        super(a1);
        this.b1 = b1;
    }
}

我遇到了一个错误,说B中的builder()无法覆盖A中的builder(),因为BBuilder中的返回类型与ABuilder中的返回类型不兼容。

是否有一种使用lombok的方法可以解决这个问题? 除非没有其他选择,否则我不想为B编写完整的构建器。

PS:由于Issue,我为B类提供了显式构造函数。 我尝试搜索,但找不到一个好的解决方案。

5个回答

26

在这里我们只需要调用构建器的超类(super)。

@Data
public class B extends A {
    Integer b1;

    @Builder
    public B(Integer b1, Integer a1) {
        super(a1);
        this.b1 = b1;
    }

    public static class BBuilder extends ABuilder{
            BBuilder() {
                super();
            }
    }
}

10
如果父类也有@Builder注解,那么这个解决方案将无法运行。 - realPK

17

父类和子类都应该标记为@SuperBuilder

将父类和子类都标记为@Builder不起作用。

父类A:

@Data
@SuperBuilder
public class A {
    Integer a1;
}

子类 B:

@Data
@SuperBuilder
public class B extends A {
    Integer b1;
}

12

Lombok在版本1.18.2中引入了实验性功能,用于解决Builder注释面临的继承问题,并可使用@SuperBuilder注释解决。

请在子/父类中使用Lombok版本1.18.2和@SuperBuilder注释。


11
如果您使用的是Lombok 1.18.4和IntelliJ,以下代码应该适用于您:
@Data
@Builder
class A {
    Integer a1;
}

@Data
class B extends A {
    Integer b1;

    @Builder (builderMethodName = "BBuilder")
    public B(Integer b1, Integer a1) {
        super(a1);
        this.b1 = b1;
    }
}

public class Main {

    public static void main(String[] args){
    System.out.println(B.BBuilder().a1(1).b1(1).build());

    }
}

顺便提一下,在撰写本答案时,@SuperBuilder注释在IntelliJ中无法正常工作。如果您有多层继承,请避免使用Lombok,否则它会使您的Java模型变得混乱。


1
澄清一下,这并不意味着可以执行 A.builder()B.builder() - zr0gravity7
1
澄清一下,这并不允许执行A.builder()B.builder() - undefined

2

经过长时间的尝试,我找到了一个可行的解决方案,而不需要使用@SuperBuilder。考虑以下示例 -

public class A{
    int x;
    
    @Builder(toBuilder = true)
    public A(int x){
        this.x = x;
    }
    
    public static class ABuilder{
        protected ABuilder(){} //Note this is important, otherwise BBuilder won't be able to access private no-args constructor of ABuilder
    }
}

public class B extends A{
    
    @Builder(builderMethodName="BBuilder", toBuilder=true)
    public B(int x){
        super(x);
    }
    
    public static class BBuilder extends ABuilder{
        BBuilder(){
            super();
        }
    }
}

public static void main(){
    B obj = new B();
    //we can use the existing obj as  obj.toBuilder().x(5).build();
    //this will return an object of B and not A

}

附言:我不确定@SuperBuilder是否仍然是实验性功能;所以不想冒险。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接