@Builder annotation produces complex builder APIs for your classes.
@Builder lets you automatically produce the code required to have your class be instantiable with code such as:
Person.builder().name("Adam Savage").city("San Francisco").worksAt("Mythbusters").build();
@Builder can be placed on a class, or on a constructor, or on a static method. While the "on a class" and "on a constructor"
mode are the most common use-case,
@Builder is most easily explained with the "static method" use-case.
A static method annotated with
@Builder (from now on called the target) causes the following 7 things to be generated:
- An inner static class named
FooBuilder, with the same type arguments as the static method (called the builder).
- In the builder: One private non-static non-final field for each parameter of the target.
- In the builder: A package private no-args empty constructor.
- In the builder: A 'setter'-like method for each parameter of the target: It has the same type as that parameter and the same name.
It returns the builder itself, so that the setter calls can be chained, as in the above example.
- In the builder: A
build() method which calls the static method, passing in each field. It returns the same type that the
- In the builder: A sensible
- In the class containing the target: A
builder() method, which creates a new instance of the builder.
Each listed generated element will be silently skipped if that element already exists (disregarding parameter counts and looking only at names). This
includes the builder
itself: If that class already exists, lombok will simply start injecting fields and methods inside this already existing
class, unless of course the fields / methods to be injected already exist. You may not put any other method (or constructor) generating lombok annotation
on a builder class though; for example, you can not put
on the builder class.
Now that the "static method" mode is clear, putting a
@Builder annotation on a constructor functions similarly; effectively,
constructors are just static methods that have a special syntax to invoke them: Their 'return type' is the class they construct, and their
type parameters are the same as the type parameters of the class itself.
@Builder to a class is as if you added
@AllArgsConstructor(access = AccessLevel.PACKAGE) to the class and applied the
@Builder annotation to this all-args-constructor. This only works if you haven't written any explicit constructors yourself. If you do have an
explicit constructor, put the
@Builder annotation on the constructor instead of on the class.
The name of the builder class is
FoobarBuilder, where Foobar is the simplified, title-cased form of the return type of the
target - that is, the name of your type for
@Builder on constructors and types, and the name of the return type for
on static methods. For example, if
@Builder is applied to a class named
com.yoyodyne.FancyList<T>, then the builder name will be
@Builder is applied to a static method that returns
void, the builder will be named
The configurable aspects of builder are:
- The builder's class name (default: return type + 'Builder')
- The build() method's name (default:
- The builder() method's name (default:
- The 'fluent' nature of the generated 'setter'-like methods. A fluent 'setter' is named just
fieldName(), a non-fluent one is named
- The 'chain' nature of the generated 'setter'-like methods. A chainable 'setter' returns the builder object itself, letting you chain 'set' calls. A non-chainable setter returns
Example usage where all options are changed from their defaults:
@Builder(builderClassName = "HelloWorldBuilder", buildMethodName = "execute", builderMethodName = "helloWorld", fluent = false, chain = false)
Another strategy for fluent APIs is that the programmer using your library statically imports your 'builder' method. In this case, you might want to name your builder
method equal to your type's name. So, the builder method for a class called
Person would become
person(). This is nicer if the builder method
is statically imported.
If the return type of your target static method is a type parameter (such as
T), lombok will enforce an explicit builder class name.
You don't HAVE to use
@Builder to build anything; you can for example put it on a static method that has lots of parameter to improve the API of it.
In this case, we suggest you use
buildMethodName = to rename the build method to
The builder class will NOT get an auto-generated implementation of
equals methods! These would suggest that it is sensible to use
instances of a builder as keys in a set or map. However, that's not a sensible thing to do. Hence, no
Generics are sorted out for you.
If an explicit constructor is present, but
@Builder is placed on the class, then the builder will be generated as if an explicit constructor is present with the
same arguments list as what
@AllArgsConstructor would produce. If this constructor does not exist, a compile time error will result. Usually you should just either let
lombok make this constructor (delete your constructor from the source), or, move the
@Builder annotation to the constructor.