While developing a project in Java, we tend to repeat the similar kind of code for each class we create. Such kind of repetitive code is generally called boilerplate code. Our next question might be like ‘Can we get rid of such multiple lines of code in real time development?’ Then answer of your question is simply ‘Yes’. The next question should be ‘How can we reduce such kind of boilerplate code?’ Now the answer is ‘with the help of Lombok API, some people call it Lombok Project’. However, as the title ” How To Reduce Boilerplate Code In Java Using Lombok Annotations” suggests, our focus in this article will be on the Lombok API Annotations.
Furthermore, the ‘Lombok API’ is highly being used in the software industry to save lots of time & effort. Hence, it becomes more important to learn all about Lombok like What is Lombok?, how to use it?, where to use it?, what are the limitations on using it? etc. in detail. Now let’s get into our topic “How To Reduce Boilerplate Code In Java Using Lombok Annotations”.
What is Lombok API or Lombok Project ?
People in the industry use word Lombok Project, Lombok API, Lombok Library interchangeably. Of course, it is an open source Java API which automates the creation of boilerplate code like getter(), setter(), equals(), hashCode(), toString(), constructors etc… and reduces the time spent in writing such kind of codes just by adding annotations to your classes & its members.
For example, suppose you have a class and you don’t want to implement its toString() method manually in your class. Then all you have to do is : add the @ToString at the top of your class. Simultaneously, the Lombok Project will use the fields of your class to implement the toString() method behind the scenes. Now, what will happen behind the scene? The implementation of toString() method will exist in compiled (.class) file but you can’t see it in your source (.java) file. Furthermore, Lombok modifies the source code before sending it to the compiler behind the scene.
What are the benefits of using Lombok ?
You might think that if we can generate code automatically with the help of an IDE (like Eclipse/STS etc.), then what will be the benefit of using Lombok? For example, suppose you have a POJO class containing 10 fields/properties. In the middle of development if you want to change number of fields, or name of field or datatype of field. Then you must either update the implementation of getterXXX(), setterXXX(), toString(), equals(), hashCode(), parameterized constructors etc. or remove them & regenerate once again. But if you use Lombok library, you don’t need to make any changes in mentioned methods or parameterized constructors. Lombok will take care of it and automatically update the changes in .class file.
Moreover, if you remove any field from the class, Lombok will remove the same from .class file. In summary, you have to just declare the fields in your class and apply the annotations accordingly.
Where can we use Lombok API/Lombok Project ?
Project Lombok can be configured in the following IDEs.
Spring Tool Suite (STS)
JBoss Developer Studio
Visual Studio Code
How to configure Lombok in eclipse/STS?
We will configure Lombok in IDE(STS/Eclipse) so that we can take benefit of the annotations provided by it in our java classes.
Step#1: Download the Lombok.jar from projectlombok.org
If you are working on Maven project, provide the dependency of ‘Lombok’ in pom.xml
and find the Lombok jar from location:
In case of STS, you can add Lombok as a starter project (want to know steps? click here).
Step#2: Double click on the jar, you will see below screen with red chilli symbol.
Step#3: It will automatically find the locations of installation of STS/Eclipse. If not, click on the ‘specify location’ and provide the path of your STS/Eclipse installation
Step#4: Make sure the checkbox is clicked, then click on install/update
Step#5: Don’t forget to restart your STS/Eclipse
How To Reduce Boilerplate Code In Java Using Lombok Annotations?
Note : All explained parameters with Annotations are optional, just for knowledge purpose. In fact, we can use every annotation without specifying any parameter.
@Getter creates getter methods for members of a class. However, it can be used at class level & field level. Also, if applied at the class level, will generate getter methods for all fields. But if applied at field level, will generate getter of the same field only. For boolean fields it adds ‘is’ prefix in place of ‘get’. Further, below snapshot is self explanatory.
@Setter creates setter methods for members of a class. However, it can be used at class level & field level. Also, if applied at the class level, will generate setter methods for all fields. But if applied at field level, will generate setter of the same field only.
Optional parameter on @Getter and @Setter
@Getter and @Setter can take optional parameter to declare access level for generated method like below. In that case code will be generated on the basis of the annotated access level.
@ToString creates an implementation of toString() method. By default It will not include any static field in the implementation of toString(). Further, we can exclude the specific field in the implemntation of toString() by using optional parameter ‘exclude’. We can also include the output of the toString() method of super class by setting optional parameter ‘callSuper’ to true.
This annotation creates both equals() and hashCode() methods as both are tied together by the hashCode contract. By default both methods will include all fields except which are static and transient. Like @ToString ‘exclude’ parameter prevents a field from being included in the implemented methods. Also like @ToString we can optionally include ‘callSuper’ parameter.
When the @NonNull annotation is placed before a method parameter, or constructor parameter, it means that this method will not accept null as an argument. If you pass to it a null object, the method will automatically raise a NullPointerException. In fact, by using this annotation, you avoid having to manually check and to manually raise NullPointerException. Generally, this annotation is used by @RequiredArgsConstructor to indicate that variable is selected for parameterized constructor creation.
We use this annotation to provide selected fields as parameters inside constructor, ie Parameterized constructor. Also Field should be selected using @NonNull annotation. Furthermore, if no field has this annotation, then zero field selected and it generates the default constructor only. This will also include fields in the constructor creation which are declared final.
This annotation is a combination of the @ToString, @EqualsAndHashCode, @Getter, @Setter and @RequiredArgsConstructor annotations.
This annotation generates Default constructor for our class.
This annotation generates all param constructor for our class. In addition, it generates default constructor if no fields found. If field exists then parameterized constructor is generated.
It will tell Project Lombok to automatically close this resource once it is no longer in use in the current scope like FileInputStream. It ensures the variable declaration that you annotate will be cleaned up by calling its close method, regardless of what happens.
This annotation when used with a class creates Builder for all instance fields available in the class.
@Builder on Constructors: If you want to create Builder for some specific fields, create a parameterized constructor using those fields and apply @Builder on that constructor.
@Builder on Methods: Like constructor, If you want to create Builder for some specific fields, create a parameterized method using those fields and apply @Builder to that method.
However, @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.
In case of a Java program with exceptions, Java requires that we must either declare or handle a checked exception. Otherwise, the code will show us compilation errors. If we use @SneakyThrows, we don’t have to either declare or handle checked exceptions. Now let’s consider following program which will force us to declare or handle ArithmeticException & ArrayIndexOutOfBoundsException. In fact, if we use @SneakyThrows, we don’t get any compilation errors.
@CommonsLog, @Slf4j, @Log4j, @Log4j2, @Flogger, @Log, @XSlf4j, @JBossLog
There are various Logging Annotations. When applied on the class, they will create a Logger instance as ‘log’ that can be used further in methods. Although we will do this exercise with different Logging libraries. Also, make sure you have included jars as dependency provided in comments of each class mentioned in the below code snippet accordingly. However, we will test all of them in a single class. Subsequently, you are supposed to create a separate class as a particular library you need to implement.
Can we use Lombok API in our real time project ?
Yes Of coarse. In fact, many developers who are familiar with this API are using Lombok in their project development to minimize the coding & effort. It also helps us in avoiding habit of writing repetitive code. However, it always depends on your project guidelines whether to use third party API like Lombok or not.
We went through all the useful annotations of Lombok Project. Now we should be in a position to use Lombok in our projects. This is all about ‘How To Reduce Boilerplate Code In Java Using Lombok Annotations’. Further, if there is any update in Lombok API, we will update here only. If you find anything interesting, don’t hesitate to put your comment. Also, let us know if you have learned something from the article header ‘How To Reduce Boilerplate Code In Java Using Lombok Annotations’.