Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make Lombok's builder public?

Tags:

I am using Lombok library in my project and I am not able to use a class annotated with @Builder in outer packages.

Is there a way to make the builder public?

MyClass instance = new MyClass.MyClassBuilder().build(); 

The error is:

'MyClassBuilder()' is not public in 'com.foo.MyClass.MyClassBuilder'. Cannot be accessed from outside package

like image 793
H.abidi Avatar asked Jan 18 '18 09:01

H.abidi


People also ask

Does Lombok builder use setter?

We already have a full introduction into Lombok's features. @Data generates all the boilerplate that is normally associated with a simple POJO (Plain Old Java Object): getters for all fields, setters for all non-final fields, and appropriate toString, equals and hashCode implementations, and a constructor.

What is @builder toBuilder true?

If using @Builder to generate builders to produce instances of your own class (this is always the case unless adding @Builder to a method that doesn't return your own type), you can use @Builder(toBuilder = true) to also generate an instance method in your class called toBuilder() ; it creates a new builder that starts ...

Is Lombok builder immutable?

One of the key features of Project Lombok is the @Builder annotation, which automatically creates Builder classes for creating immutable objects.

What is difference between @builder and SuperBuilder?

The @SuperBuilder annotation produces complex builder APIs for your classes. In contrast to @Builder , @SuperBuilder also works with fields from superclasses. However, it only works for types. Most importantly, it requires that all superclasses also have the @SuperBuilder annotation.


1 Answers

@Builder already produces public methods, it's just the constructor that's package-private. The reason is that they intend for you to use the static builder() method, which is public, instead of using the constructor directly:

Foo foo = Foo.builder()     .property("hello, world")     .build(); 

If you really, really, really want the constructor to be public (there seems to be some suggestion that other reflection-based libraries might require it), then Lombok will never override anything that you've already declared explicitly, so you can declare a skeleton like this with a public constructor and Lombok will fill in the rest, without changing the constructor to package-private or anything.

@Builder public class Foo {     private final String property;      public static class FooBuilder     {         public FooBuilder() { }          // Lombok will fill in the fields and methods     } } 

This general strategy of allowing partial implementations to override default behaviour applies to most (maybe all) other Lombok annotations too. If your class is annotated with @ToString but you already declared a toString method, it will leave yours alone.

Just to show you everything that gets generated, I wrote the following class:

@Builder public class Foo {     private final String property; } 

I then ran it through delombok to see everything that was generated. As you can see, everything is public:

public class Foo {     private final String property;      @java.beans.ConstructorProperties({"property"})     Foo(final String property) {         this.property = property;     }      public static FooBuilder builder() {         return new FooBuilder();     }      public static class FooBuilder     {         private String property;          FooBuilder() { }          public FooBuilder property(final String property) {             this.property = property;             return this;         }          public Foo build() {             return new Foo(property);         }          public String toString() {             return "Foo.FooBuilder(property=" + this.property + ")";         }     } } 
like image 74
Michael Avatar answered Sep 24 '22 04:09

Michael