Project Lombok is a very useful tool for java projects to reduce boiler plate code.
In Java vs. other language debate, the first knock which you get from other language supporters is that Java requires lot of boiler plate code and you just cannot get over it, and you are defenceless. The same issue is also reported in multiple platforms and developer communities. Let’s see a sample of code which has boiler plate code.
package com.askrakesh.java.manage_boilerplate;
import java.time.LocalDate;
public class Person {
String firstName;
String lastName;
LocalDate dateOfBirth;
public Person(String firstName, String lastName, LocalDate dateOfBirth) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public LocalDate getDateOfBirth() {
return dateOfBirth;
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((dateOfBirth == null) ? 0 : dateOfBirth.hashCode());
result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result + ((lastName == null) ? 0 : lastName.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (dateOfBirth == null) {
if (other.dateOfBirth != null)
return false;
} else if (!dateOfBirth.equals(other.dateOfBirth))
return false;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
return true;
}
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + "dateOfBirth=" + dateOfBirth + "]";
}
}
A class should have getter-setters for the instance variables, equals
& hashCode
method implementation, all field constructors and an implementation of toString
method. This class so far has no business logic and even without it is 80+ lines of code. This is insane.
Project Lombok is a java library that automatically plugs into your editor and build tools and helps reduce the boiler plate code. Let’s see how to setup Lombok project first.
Lombok has various annotations which can be used within our code that is be processed during the compile time and appropriate code expansion would take place based on the annotation used. Lombok only does the code reduction in view time, after the compiling the byte code is injected with all the boiler plate. This helps keeping our codebase small, clean and easy to read and maintain.
Adding Lombok in your project is simple. Just add the below dependency in your maven project pom.xml file.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
Here are the installation steps for Windows:
java -jar lombok.jar
If you are on MacOS, then following are the steps to use Lombok in your project.
Eclipse.app/Contents/MacOS
directory.-javaagent:lombok.jar
to the end of Eclipse.app/Contents/Eclipse/eclipse.ini
file.After installation let’s check how we can see our reduced boiler plate code? I have recreated the same class as PersonLombok
. Eclipse outline which displays getter and setter for firstName. This was done based on the Lombok’s @Getter
& @Setter
annotation set for instance variable firstName.
We can check the addition of getter & setter methods for the firstName from class bytecode.
Project Lombok provides many annotation which helps to reduce the boiler plate code in various scenarios. Let’s go through a few of them.
@AllArgsConstructor
public class PersonLombok {
@NonNull String firstName;
String lastName;
LocalDate dateOfBirth;
public static void main(String[] args) {
new PersonLombok(null, "Kumar", LocalDate.now());
}
}
Above code injects the following in the class:
Here’s the result of the program run. @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.
These annotations can be used either at the field or class level. If you want fine grained control then use it at field level. When used at class level all the getter/setters are created. Let’s work on the class we had created above.
@AllArgsConstructor @Getter @Setter
public class PersonLombok {
String firstName;
String lastName;
LocalDate dateOfBirth;
}
It’s recommended to override the hashCode()
and equals()
methods while creating a class. In Lombok we have @EqualsAndHashCode
annotation which injects code for equals() & hashCode() method as they go together. Additionally a @ToString
annotation provides a toString() implementation. Let’s see this:
@AllArgsConstructor @Getter @Setter
@EqualsAndHashCode
@ToString
public class PersonLombok {
String firstName;
String lastName;
LocalDate dateOfBirth;
}
We now have achieved to create Person class without any boiler plate code with help of Lombok annotations. However it gets even better we can replace all the annotations used in the above class with @Data
and get the same functionality.
@Builder
lets you automatically produce the code required to have your class be instantiable using builder pattern.
@Builder
public class Employee {
String firstName;
String lastName;
LocalDate dateOfBirth;
public static void main(String[] args) {
Employee emp = new EmployeeBuilder().firstName("Rakesh")
.lastName("Kumar")
.dateOfBirth(LocalDate.now())
.build();
}
}
@Delegate
generates delegate methods that forward the call to this field on which annotation is used. “Favour Composition over Inheritance”, but this creates a lot of boiler plate code similar to Adapter Pattern. Lombok’s took the clue from Groovy’s annotation by the same name while implementing this functionality. Let’s see an implementation:
@RequiredArgsConstructor
public class AdapterImpl implements Adapter {
@Delegate
private final Adaptee instance;
public static void main(String[] args) {
AdapterImpl impl = new AdapterImpl(new Adaptee());
impl.display();
}
}
interface Adapter {
public void display();
}
class Adaptee {
public void display() {
System.out.println("In Adaptee.display()");
}
}
Lombok provides functionality for fine grained control in all the annotations.
Yes, they are. You need to understand unlike other languages, Java has taken utmost care of upgrading the language such that they do not break any existing codebase which are in older versions of java. This itself is a huge task and cannot be undermined. They are already modifying and building better type inference capabilities in the language which has been rolled out. One of the important features planned for Java 10 is Local-Variable Type Inference. Though the feature has more to do with adding dynamic typing than the boiler plate, but it is a small drop in the Ocean to manage the boiler-plate code.
Reducing boiler plate code helps in better readability, less code also means less error. Project Lombok is heavily used today in almost all the major organizations. We provided you with the most useful features from Lombok. Hope you give it a try. Source Code: You can visit my Github link to download complete source code used in this tutorial.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
Good Article. Very informative.
- Anooplal
Very well written and documented article.
- Amy