How to run code after constructor in a Lombok builder

Budius picture Budius · Jun 22, 2016 · Viewed 13.1k times · Source

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 val1;
   public int val2;
   public List<String> listValues;

   public void init(){
       // do some checks with the values.
   }
}

normally I would just call init() on a NoArg constructor, but with the generated builder I'm unable to do so. Is there a way for this init be called by the generated builder? For example build() would generate a code like:

public Foo build() {
   Foo foo = Foo(params....)
   foo.init();
   return foo;
}

I'm aware that I can manually code the all args constructor, that the Builder will call through it and I can call init inside there.

But that is a sub-optimal solution as my class will likely have new fields added every once in a while which would mean changing the constructor too.

Answer

Budius picture Budius · Jun 22, 2016

After much trial and end error I found a suitable solution: extend the generate builder and call init() myself.

Example:

@Builder(toBuilder = true, builderClassName = "FooInternalBuilder", builderMethodName = "internalBuilder")
public class Foo {

   public String val1;
   public int val2;
   @Singular public List<String> listValues;

   void init() {
      // perform values initialisation
   }

   public static Builder builder() {
      return new Builder();
   }

   public static class Builder extends FooInternalBuilder {

      Builder() {
         super();
      }

      @Override public Foo build() {
         Foo foo = super.build();
         foo.init();
         return foo;
      }
   }
}