【问题标题】:Lombok return custom build object in builderLombok 在构建器中返回自定义构建对象
【发布时间】:2018-11-01 23:21:44
【问题描述】:

我有一个无法修改的类,但希望有一个构建器。我正在使用龙目岛。

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class SampleClass {
    private String a;
    private String b;
}

为了有一个构建器,我创建了一个 BuilderClass:

@Builder
public class SampleClassBuilder {
    private String x;
    private String y;

    public SampleClass build() {
        SampleClass sampleClass = new SampleClass();
        sampleClass.setA(x + "testX");
        sampleClass.setB(y + "textY");
        return sampleClass;
    }
}

要使用它,我需要这样做:

SampleClass sampleClass = SampleClassBuilder.builder().x("x -- ").y("y---").build().build();

有没有办法覆盖 build 方法以返回 SampleClass 以避免执行 build.build?

【问题讨论】:

    标签: java java-8 lombok


    【解决方案1】:

    我不认为 Lombok 可以做到这一点:从 Builder 返回另一个对象。它甚至不能在builder中调用super。

    也许您可以不使用 Lombok 来定义自己的构建:

    public class SampleBuilder {
        private String x;
        private String y;
    
        public static SampleBuilder builder() {
            return new SampleBuilder();
        }
    
        private SampleBuilder() {
        }
    
        public SampleBuilder x(String x) {
            this.x = x;
            return this;
        }
    
        public SampleBuilder y(String y) {
            this.y = y;
            return this;
        }
    
        public SampleClass build() {
            SampleClass sampleClass = new SampleClass();
            sampleClass.setA(x + "testX");
            sampleClass.setB(y + "textY");
            return sampleClass;
        }
    }
    

    在你的客户端代码中,你可以看到Lombok's likebuilder的用法:

    SampleClass obj = SampleBuilder.builder().x("x").y("y").build();
    

    【讨论】:

    • 是的,我正在考虑像你提到的那样编写一个自定义构建器,但想知道 Lombok 是否有任何替代方式。我想我必须选择这个选项。
    • 幸运的是,Lombok 并不那么聪明。它可以完成一些非常常见的任务。
    • 是的。我最接近的是stackoverflow.com/questions/37968696/… 但是我无法在覆盖时更改返回类型
    【解决方案2】:

    如果您只需要自定义构建器的设置器(如 .x(...) .y(...) 但不是自定义 .build()),您可以添加 SampleClassBuilder 作为静态内部类来覆盖一些 Lombok 设置器方法。

    @Builder // <--- Put @Builder at the SampleClass itself, not at Builder class
    @ToString
    class SampleClass { // Lombok will internally create SampleClassBuilder
    
        private String x;
        private String y;
        private int a,b,c;
        private String z;
    
        public static class SampleClassBuilder{ // Need to name like this to override Lombok class
            public SampleClassBuilder x(String x){
                this.x = x + "testX"; // Lombok will also create `this.x` for this builder class (also y,a,b,c,z)
                return this;
            }
            public SampleClassBuilder y(String y){
                this.y = y + "testY";
                return this;
            }
            public SampleClassBuilder z(String z){
                this.z = this.x + this.y; // *`.z()` must be called lastly if refer to other fields
                return this;
            }
        }
    

    要使用它,您只需这样做:

    SampleClass sample = SampleClass.builder().x("One").z(null).y("Two").a(1).b(2).c(3).build();
    System.out.println(sample); // SampleClass(x=OnetestX, y=TwotestY, a=1, b=2, c=3, z=OnetestXnull)
    

    *请注意,使用这种模式,.z(...)需要在其他人之后调用;否则,该值将错误为z="OnetestXnull",因为当时ynull

    要解决这个问题:

    • 您可以将this.z(null) 附加到方法x()y()
    • 或者,在此处使用另一种模式:https://stackoverflow.com/a/65773183/2710335 以避免将this.z(null) 放在任何地方(例如this.z = this.x + this.y + this.a + this.b + this.c + ...;)。

    【讨论】:

      猜你喜欢
      • 2020-10-04
      • 2023-03-29
      • 2018-04-14
      • 2017-05-24
      • 2021-07-20
      • 2014-11-08
      • 2019-11-24
      • 1970-01-01
      相关资源
      最近更新 更多