Lombok is a java annotation processor which generates boilerplate code automatically in your classes at compile time. Many of lombok's feature overlap with features in the groovy language and AST Transformations. Let us look at some of those features.
val creates a type inferred, final local variable.
the type will be inferred from the initializer expression. The local variable will also be made final.
var creates a type inferred, local variable.
var works exactly like val, except the local variable is not marked as final.
Groovy has support for
var. Since groovy is optionally typed these keywords do not normally provide type inference.
def and var act as a type placeholder, i.e. a replacement for the type name, when you do not want to give an explicit type. (see variable definition)
When code is annotated with @TypeChecked, the compiler performs type inference. It doesn’t simply rely on static types, but also uses various techniques to infer the types of variables, return types, literals, … so that the code remains as clean as possible even if you activate the type checker.
To get the behavior of
val in groovy apply
@TypeChecked and declare a variable with
var and the
@TypeChecked def final variable = '123'
Lombok will generate null checks for any generate method which involves a field marked with
Lombok has always treated various annotations generally named @NonNull on a field as a signal to generate a null-check if lombok generates an entire method or constructor for you, via for example @Data.
Groovy has @NullCheck which provides similar capabilities.
Class, method or constructor annotation which indicates that each parameter should be checked to ensure it isn't null. If placed at the class level, all explicit methods and constructors will be checked.
Lombok has several advantages over groovy. With lombok, if a field is marked with
@NonNull all generated methods will perform null checks. In groovy this is not the case.
includeGenerated must be set to true for groovy to generate null checks in generated code. When this option is applied in groovy code may still not have a null check. This issue appears to be fixed in groovy 4.
Lombok does not support
@NonNull at the class level. This may be considered a disadvantage for some. Each parameter for non-generated methods must be explicitly declared as
@NonNull. Lombok does guarantee that null checks will be created for all generated code.
You can use
@Cleanupto ensure a given resource is automatically cleaned up before the code execution path exits your current scope.
This feature is not supported by groovy although groovy does support additional idioms for automatic resource management with the use of closures.
Lombok will generate getters and setters for all fields marked with these annotations. If the class is marked with these annotations all fields will have getters and setters generated. A developer may still supply one of these methods and lombok will keep the original method.
Getters and setters are automatically generated for properties in a groovy class. The getter and setter can be overridden by writing it in the class. Scope can be changed by overriding the method. Properties marked with
final will not generate a setter.
Any class definition may be annotated with
@ToStringto let lombok generate an implementation of the toString() method. By default, it'll print your class name, along with each field, in order, separated by commas.
Any class definition may be annotated with
@EqualsAndHashCodeto let lombok generate implementations of the equals(Object other) and hashCode() methods.
These annotations create constructors for the class. Required args is any final or uninitialized field with the
@TupleConstructor which is able to create one constructor with a specific configuration.
It is not possible to create multiple constructors on one class with
@TupleConstructor. This is the advantage of having multiple annotations in lombok.
@Datais a convenient shortcut annotation that bundles the features of @ToString, @EqualsAndHashCode, @Getter / @Setter and @RequiredArgsConstructor together: In other words, @Data generates all the boilerplate that is normally associated with simple POJOs (Plain Old Java Objects) and beans: getters for all fields, setters for all non-final fields, and appropriate toString, equals and hashCode implementations that involve the fields of the class, and a constructor that initializes all final fields, as well as all non-final fields with no initializer that have been marked with @NonNull, in order to ensure the field is never null.
Groovy has the
@Cononical AST which combines
@Valueis the immutable variant of @Data; all fields are made private and final by default, and setters are not generated. The class itself is also made final by default, because immutability is not something that can be forced onto a subclass.
Groovy provides the @Immutable annotation.
@Builderannotation produces complex builder APIs for your classes.
Groovy provides the
@SneakyThrowscan be used to sneakily throw checked exceptions without actually declaring this in your method's throws clause.
In groovy all exceptions are optional and do not need to be declared.
@Synchronizedis a safer variant of the synchronized method modifier.
@Synchronized already exists in groovy and works in exactly the same way.
The next best alternative to a setter for an immutable property is to construct a clone of the object, but with a new value for this one field. A method to generate this clone is precisely what
@Withgenerates: a withFieldName(newValue) method which produces a clone except for the new value for the associated field.
Similar methods to @With can be created in groovy with @Builder but the object is not immutable.
@Builder(builderStrategy=SimpleStrategy, prefix = 'with')
@Getter(lazy=true) annotation creates a cached version of a getter method.
You can let lombok generate a getter which will calculate a value once, the first time this getter is called, and cache it from then on.
It is possible to use
You put the variant of
@Logon your class (whichever one applies to the logging system you use); you then have a static final log field, initialized as is the commonly prescribed way for the logging framework you use, which you can then use to write log statements.