How to run code after constructor in a Lombok builder

后端 未结 4 1646
庸人自扰
庸人自扰 2021-02-07 01:38

I have a class that I want to use Lombok.Builder and I need pre-process of some parameters. Something like this:

@Builder
public class Foo {
   public String val         


        
4条回答
  •  深忆病人
    2021-02-07 01:56

    I just stumbled upon the same issue. But additionally, I wanted to add an method buildOptional() to the builder to not repeat Optional.of(Foo) each time I need it. This did not work with the approach posted before because the chained methods return FooInternalBuilder objects; and putting buildOptional() into FooInternalBuilder would miss the init() method execution in Builder...

    Also, I personally did not like the presence of 2 builder classes.

    Here is what I did instead:

    @Builder(buildMethodName = "buildInternal")
    @ToString
    public class Foo {
        public String val1;
        public int val2;
        @Singular  public List listValues;
    
        public void init(){
            // do some checks with the values.
        }    
    
        /** Add some functionality to the generated builder class */
        public static class FooBuilder {
            public Optional buildOptional() {
                return Optional.of(this.build());
            }
    
            public Foo build() {
                Foo foo = this.buildInternal();
                foo.init();
                return foo;
            }
        }
    }
    

    You can do a quick test with this main method:

    public static void main(String[] args) {
        Foo foo = Foo.builder().val1("String").val2(14)
                .listValue("1").listValue("2").build();
        System.out.println(foo);
    
        Optional fooOpt = Foo.builder().val1("String").val2(14)
                .listValue("1").listValue("2").buildOptional();
        System.out.println(fooOpt);
    }
    

    Doing so let's you add what I want:

    • Add an init() method which is executed after each object construction automatically
    • Adding new fields do not require additional work (as it would be for an individually written constructor)
    • Possibility to add additional functionality (incl. the init() execution)
    • Retain the complete standard functionality the @Builder annotation brings
    • Don't expose an additional builder class

    Even if you solved your problem before I like to share this as the solution. It is a bit shorter and adds a (for me) nice feature.

提交回复
热议问题