Never write another getter or equals method again using Project Lombok. Early access to future java features such as val
and much more.
Project Lombok is a java library that automatically plugs into your editor and builds tools, spicing up your java.
Check this amazing Project Lombok demo
Features of Project Lombok
Installation of Project Lombok is given at last of this post. So firstly check top 10 features of Lombok.
val

Finally! Hassle-free final local variables.
You can use val
 as the type of a local variable declaration instead of actually writing the type. When you do this, the type will be inferred from the initializer expression. The local variable will also be made final. This feature works on local variables and on foreach loops only, not on fields. The initializer expression is required.
val
 is actually a ‘type’ of sorts, and exists as a real class in the lombok
 package. You must import it for val to work (or use lombok.val
 as the type). The existence of this type on a local variable declaration triggers both the adding of the final
 keyword as well as copying the type of the initializing expression which overwrites the ‘fake’ val
 type.
Example of val:
import java.util.ArrayList; import java.util.HashMap; import lombok.val; public class ValExample { public String example() { val example = new ArrayList<String>(); example.add("Hello, World!"); val foo = example.get(0); return foo.toLowerCase(); } public void example2() { val map = new HashMap<Integer, String>(); map.put(0, "zero"); map.put(5, "five"); for (val entry : map.entrySet()) { System.out.printf("%d: %s\n", entry.getKey(), entry.getValue()); } } }
WARNING: This feature does not currently work in NetBeans.
var

Mutable! Hassle-free local variables.
var
 works exactly like val
, except the local variable is not marked as final
.
The type is still entirely derived from the mandatory initializer expression, and any further assignments, while now legal (because the variable is no longer final
), aren’t looked at to determine the appropriate type.
[tmh_article_ads]
For example, var x = "Hello"; x = Color.RED;
 does not work; the type of x will be inferred to be java.lang.String
and thus, the x = Color.RED
 assignment will fail. If the type of x
 was inferred to be java.lang.Object
 this code would have compiled, but that’s not howvar
 works.
@NonNull

How I learned to stop worrying and love the NullPointerException.
You can use @NonNull
 on the parameter of a method or constructor to have lombok generate a null-check statement for you.
Lombok has always treated any annotation 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
. Now, however, using lombok’s own @lombok.NonNull
 on a parameter results in the insertion of just the null-check statement inside your own method or constructor.
The null-check looks like if (param == null) throw new NullPointerException("param is marked @NonNull but is null");
 and will be inserted at the very top of your method. For constructors, the null-check will be inserted immediately following any explicit this()
 or super()
 calls.
If a null-check is already present at the top, no additional null-check will be generated.
Example of @NonNull:
import lombok.NonNull; public class NonNullExample extends Something { private String name; public NonNullExample(@NonNull Person person) { super("Hello"); this.name = person.getName(); } }
@Cleanup

Automatic resource management: Call your close()
 methods safely with no hassle.
You can use @Cleanup
 to ensure a given resource is automatically cleaned up before the code execution path exits your current scope. You do this by annotating any local variable declaration with the @Cleanup
 annotation like so:
@Cleanup InputStream in = new FileInputStream("some/file");
As a result, at the end of the scope you’re in, in.close()
 is called. This call is guaranteed to run by way of a try/finally construct. Look at the example below to see how this works.
If the type of object you’d like to cleanup does not have a close()
 method, but some other no-argument method, you can specify the name of this method like so:
@Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
By default, the cleanup method is presumed to be close()
. A cleanup method that takes 1 or more arguments cannot be called via @Cleanup
.
Example of @Cleanup
import lombok.Cleanup; import java.io.*; public class CleanupExample { public static void main(String[] args) throws IOException { @Cleanup InputStream in = new FileInputStream(args[0]); @Cleanup OutputStream out = new FileOutputStream(args[1]); byte[] b = new byte[10000]; while (true) { int r = in.read(b); if (r == -1) break; out.write(b, 0, r); } } }
@Getter and @Setter

Never write againpublic int getFoo() {return foo;}
.
You can annotate any field with @Getter
 and/or @Setter
, to let lombok generate the default getter/setter automatically.
A default getter simply returns the field, and is named getFoo
 if the field is called foo
 (or isFoo
 if the field’s type is boolean
). A default setter is named setFoo
 if the field is called foo
, returns void
, and takes 1 parameter of the same type as the field. It simply sets the field to this value.
The generated getter/setter method will be public
 unless you explicitly specify an AccessLevel
, as shown in the example below. Legal access levels are PUBLIC
, PROTECTED
, PACKAGE
, and PRIVATE
.
You can also put a @Getter
 and/or @Setter
 annotation on a class. In that case, it’s as if you annotate all the non-static fields in that class with the annotation.
You can always manually disable getter/setter generation for any field by using the special AccessLevel.NONE
 access level. This lets you override the behaviour of a @Getter
, @Setter
 or @Data
 annotation on a class.
Example of @Getter/@Setter
import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; public class GetterSetterExample { /** * Age of the person. Water is wet. * * @param age New value for this person's age. Sky is blue. * @return The current value of this person's age. Circles are round. */ @Getter @Setter private int age = 10; /** * Name of the person. * -- SETTER -- * Changes the name of this person. * * @param name The new value. */ @Setter(AccessLevel.PROTECTED) private String name; @Override public String toString() { return String.format("%s (age: %d)", name, age); } }
@ToString

No need to start a debugger to see your fields: Just let project lombok generate a toString
 for you!
Any class definition may be annotated with @ToString
 to let project 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.
By setting the includeFieldNames
 parameter to true you can add some clarity (but also quite some length) to the output of the toString()
 method.
Example of @toString
import lombok.ToString; @ToString public class ToStringExample { private static final int STATIC_VAR = 10; private String name; private Shape shape = new Square(5, 10); private String[] tags; @ToString.Exclude private int id; public String getName() { return this.name; } @ToString(callSuper=true, includeFieldNames=true) public static class Square extends Shape { private final int width, height; public Square(int width, int height) { this.width = width; this.height = height; } } }
@EqualsAndHashCode

Generates hashCode
 and equals
implementations from the fields of your object.
Any class definition may be annotated with @EqualsAndHashCode
 to let lombok generate implementations of the equals(Object other)
 and hashCode()
 methods. By default, it’ll use all non-static, non-transient fields, but you can modify which fields are used (and even specify that the output of various methods is to be used) by marking type members with @EqualsAndHashCode.Include
 or @EqualsAndHashCode.Exclude
. Alternatively, you can specify exactly which fields or methods you wish to be used by marking them with @EqualsAndHashCode.Include
 and using @EqualsAndHashCode(onlyExplicitlyIncluded = true)
.
[tmh_article_ads]
If applying @EqualsAndHashCode
 to a class that extends another, this feature gets a bit trickier. Normally, auto-generating an equals
 and hashCode
 method for such classes is a bad idea, as the superclass also defines fields, which also need equals/hashCode code but this code will not be generated.
Example of @EqualAndHashCode
import lombok.EqualsAndHashCode; @EqualsAndHashCode public class EqualsAndHashCodeExample { private transient int transientVar = 10; private String name; private double score; @EqualsAndHashCode.Exclude private Shape shape = new Square(5, 10); private String[] tags; @EqualsAndHashCode.Exclude private int id; public String getName() { return this.name; } @EqualsAndHashCode(callSuper=true) public static class Square extends Shape { private final int width, height; public Square(int width, int height) { this.width = width; this.height = height; } } }
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor

Constructors made to order: Generates constructors that take no arguments, one argument per final / non-null field, or one argument for every field.
This set of 3 annotations generate a constructor that will accept 1 parameter for certain fields, and simply assigns this parameter to the field.
@NoArgsConstructor
 will generate a constructor with no parameters. If this is not possible (because of final fields), a compiler error will result instead, unless @NoArgsConstructor(force = true)
 is used, then all final fields are initialized with 0
 / false
 / null
. For fields with constraints, such as @NonNull
 fields, no check is generated,so be aware that these constraints will generally not be fulfilled until those fields are properly initialized later. Certain java constructs, such as hibernate and the Service Provider Interface require a no-args constructor. This annotation is useful primarily in combination with either @Data
 or one of the other constructor generating annotations.
@RequiredArgsConstructor
 generates a constructor with 1 parameter for each field that requires special handling. All non-initialized final
 fields get a parameter, as well as any fields that are marked as @NonNull
 that aren’t initialized where they are declared. For those fields marked with @NonNull
, an explicit null check is also generated. The constructor will throw a NullPointerException
 if any of the parameters intended for the fields marked with @NonNull
 contain null
. The order of the parameters match the order in which the fields appear in your class.
@AllArgsConstructor
 generates a constructor with 1 parameter for each field in your class. Fields marked with @NonNull
 result in null checks on those parameters.
Example of @ArgConstructor
import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import lombok.AllArgsConstructor; import lombok.NonNull; @RequiredArgsConstructor(staticName = "of") @AllArgsConstructor(access = AccessLevel.PROTECTED) public class ConstructorExample<T> { private int x, y; @NonNull private T description; @NoArgsConstructor public static class NoArgsExample { @NonNull private String field; } }
@Data

All together now: A shortcut for @ToString
, @EqualsAndHashCode
, @Getter
 on all fields, @Setter
 on all non-final fields, and @RequiredArgsConstructor
!
@Data
 is 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.
@Data
 is like having implicit @Getter
, @Setter
, @ToString
, @EqualsAndHashCode
 and @RequiredArgsConstructor
annotations on the class (except that no constructor will be generated if any explicitly written constructors already exist). However, the parameters of these annotations (such as callSuper
, includeFieldNames
 and exclude
) cannot be set with @Data
. If you need to set non-default values for any of these parameters, just add those annotations explicitly;Â @Data
 is smart enough to defer to those annotations.
Example of @Data
import lombok.AccessLevel; import lombok.Setter; import lombok.Data; import lombok.ToString; @Data public class DataExample { private final String name; @Setter(AccessLevel.PACKAGE) private int age; private double score; private String[] tags; @ToString(includeFieldNames=true) @Data(staticConstructor="of") public static class Exercise<T> { private final String name; private final T value; } }
@Synchronized

synchronized
 done right: Don’t expose your locks.
@Synchronized
 is a safer variant of the synchronized
 method modifier. Like synchronized
, the annotation can be used on static and instance methods only. It operates similarly to the synchronized
 keyword, but it locks on different objects. The keyword locks on this
, but the annotation locks on a field named $lock
, which is private.
If the field does not exist, it is created for you. If you annotate a static
 method, the annotation locks on a static field named $LOCK
 instead.
If you want, you can create these locks yourself. The $lock
 and $LOCK
 fields will of course not be generated if you already created them yourself. You can also choose to lock on another field, by specifying it as a parameter to the @Synchronized
 annotation. In this usage variant, the fields will not be created automatically, and you must explicitly create them yourself, or an error will be emitted.
Example of @Synchronised
import lombok.Synchronized; public class SynchronizedExample { private final Object readLock = new Object(); @Synchronized public static void hello() { System.out.println("world"); } @Synchronized public int answerToLife() { return 42; } @Synchronized("readLock") public void foo() { System.out.println("bar"); } }
The list is not ending here and if you like this article and want to know more feature of Project Lombok then comment us below 🙂
Share your thoughts