Introduction
Have you ever thought of writing a small piece of Java code providing greater functionality? Yes, of course, you would like to do that. It may be a good framework or a good algorithm to do so. If you can write small Java code then it will increase the readability, portability and has fewer bugs and less maintenance. In this article, I present a great framework called "Lombok" that provides an efficient way to write smaller Java code to achieve greater functionality. Lombok is a framework that provides a boilerplate structure to minimize your code to perform more. Lombok provides certain annotations that help us to write better code and eliminates the burden of repetitive code in any project. Let us dive into the usage of the Lombok framework.
Technicalities
There are certain situations where developers complain about the vast code and find it difficult to make a walkthrough. It is the absolute reality that not all code can be minimized depending on the functionalities whether they are simple or complex. In modern days, new frameworks have evolved to make the developer's life easier. Lombok is one of the frameworks to help developers to write less code and avoid rewriting repetitious code. Think about a situation where you have a bean or POJO that contains fields like id, first name, last name, salary, designation and so on and you will have all the getter and setter methods for this. It is also true that modern developers never write getter and setter methods manually. It is only because of the benefit of the sophisticated style of the modern Java IDEs, developers generate getter and setter methods and some other generic methods also. However, the code finally looks vast. There may be a POJO or a bean that may contain 2 to 3 hundred lines of code. Now the simple POJO looks bulky. It may look complex for a novice Java developer. What if we simply write the fields and let all the relevant getter and setter methods be generated at runtime? That is the power and flexibility provided by Lombok. Lombok provides the following widely used annotations.
@NonNull,@Cleanup,@Getter/@Setter,@ToString,@EqualsAndHashCode,
@NoArgsConstructor,@RequiredArgsConstructor,@AllArgsConstructor,
@Data,@Value,@Slf4j,@Log4j
Let us discuss each annotation very precisely.
@NonNull
This annotation generates a NullPointerException for null checking. This annotation can be applied in the field of a class or at the method parameter level. Let us see the code below.
- package com.ddlab.rnd.lombok;
- import lombok.NonNull;
-
-
-
-
-
-
-
- public class NonNullCheck
- {
-
- @NonNull
- private String value;
-
-
-
-
-
- public NonNullCheck(@NonNull String value) {
- this.value = value;
- }
-
-
-
- public void show()
- {
- System.out.println("Value--->" + value);
- }
-
-
-
-
-
-
- public static void main(String[] args)
- {
- NonNullCheck nc = new NonNullCheck(null);
- nc.show();
- }
- }
In the code above we are just providing @NonNull and we are not writing the code for NullPointerException.
@Cleanup
This is a very useful and handy annotation that saves our life. You have may have seen due to work pressure or for some other reason, developers forget to invoke the close method for file operations or database operation. If you provide this annotation then the code will automatically provide a close() method at runtime. It is also helpful while making code reviews so you can easily provide this annotation if the developer has forgotten to write it. Let us see the code below.
- package com.ddlab.rnd.lombok;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import lombok.Cleanup;
- import lombok.NonNull;
-
-
-
-
-
-
-
-
- public class FileReader {
-
-
-
-
-
-
-
-
-
- public static void readFile(@NonNull String filePath) throws Exception {
- File file = new File(filePath);
- byte[] buffer = new byte[(int) file.length()];
- @Cleanup
- InputStream inStream = new FileInputStream(file);
- inStream.read(buffer);
- System.out.println("File Contents :\n" + new String(buffer));
- }
-
-
-
-
-
- public static void main(String[] args) {
- try {
- FileReader.readFile("data/data.txt");
-
- } catch (Exception e) {
- e.printStackTrace();
- System.out.println("I got the exception ........");
- }
- }
- }
See the bold section of the code and you are saving your time by not writing a try and finally block and a close operation.
@Getter/@Setter
It is a common practice that whenever we write a POJO with some fields that we benefit from the intelligence of the Java IDE to generate the getter and setter methods. In this case, Lombok provides @Getter and @Setter annotations to generate the getter and setter methods at runtime. Let us look at the code below.
- package com.ddlab.rnd.lombok;
- import lombok.Getter;
- import lombok.Setter;
-
-
-
-
-
-
-
- public class Employee {
-
-
-
-
-
-
- @Getter
- @Setter
- private int id;
-
-
-
-
-
-
- @Getter
- @Setter
- private String name;
- }
Here the code looks very simple and precise.
@ToString and @EqualsAndHashCode
Sometimes it is necessary to provide toString(), equals() and hashcode() methods in a Java bean. In this case Lombok also provides the smart annotations like @ToString and @EqualsAndHashCode so that relevant code will be generated at runtime. Let us look at the code below.
- package com.ddlab.rnd.lombok;
- import lombok.EqualsAndHashCode;
- import lombok.Getter;
- import lombok.Setter;
- import lombok.ToString;
-
-
-
-
-
-
-
- @ToString
- @EqualsAndHashCode
- public class Student {
-
-
-
-
-
-
- @Getter
-
-
-
-
-
-
-
-
-
-
- @Setter
- private int rollNo;
-
-
-
-
-
-
- @Getter
-
-
-
-
-
-
-
-
-
-
- @Setter
- private String name;
-
-
-
-
-
-
-
-
- public Student(int rollNo, String name) {
- this.rollNo = rollNo;
- this.name = name;
- }
- }
In the code above I have used annotations like @Getter,@Setter,@ToString and @EqualsAndHashCode.
@Data and @Value
@Data is very handy and it is the replacement for @ToString, @EqualsAndHashCode, @Getter, @Setter on all non-final fields, and @RequiredArgsConstructor. Simply provide the @Data annotation for the class and let Lombok generate the code at runtime. Let us see the code below.
- package com.ddlab.rnd.lombok;
- import lombok.Data;
-
-
-
-
-
- @Data
- public class Person {
-
- private int id;
-
- private String name;
- }
@Value annotation helps us to define our class as immutable. You can easily make your class immutable with the annotation @Value but be cautious of java.util.Date class. This annotation does not handle Date object properly. Let us see the code below.
- package com.ddlab.rnd.lombok;
- import java.util.Date;
- import lombok.Value;
-
-
-
-
-
-
-
-
-
-
-
- @Value
- public class ImmutableEmployee {
-
- private int id;
-
- private String name;
-
-
-
-
- private Date dateOfBirth;
- }
val
The val keyword in Lombok is the replacement for final. It can be applied at the class level or the member inside a method. It is not so widely used. Let us see the code below.
- package com.ddlab.rnd.lombok;
- import java.util.ArrayList;
- import lombok.val;
-
-
-
-
-
-
-
- public class UseOfVal {
-
-
-
-
-
-
- public void populateNames(String[] names){
- val nameList = new ArrayList<String>();
- for (String name : names)
- nameList.add(name);
- System.out.println("All Names : " + nameList);
- }
- }
@Slf4j and @Log4j
As you know in any application logging is an integral part and for that purpose we use the log4j or slf4j API. In this case Lombok provides @Slf4j and @Log4j annotations that can be applied in the class level. Let us see the code below.
- package com.ddlab.rnd.lombok.test;
- import lombok.extern.log4j.Log4j;
-
-
-
-
-
- @Log4j
- public class TestLog4jLogger {
-
-
-
- public static void logMessages() {
- log.debug("It is a debug statement ");
- log.info("It is an info statement ");
- log.error("It is an error statement ");
- log.warn("It is a warn statement ");
- }
- public static void main(String[] args) {
- logMessages();
- }
- }
This looks very easy and helps us to minimize our code. In the next section, we will learn about the configuration and use of Lombok.
Configuration
Lombok comes in the form of a JAR file that must be set in the classpath. Lombok can be downloaded from the following link.
If you want to use Lombok in the Eclipse IDE then just double-click the JAR file and provide the path of your Eclipse home/installation directory. You can refer to the following link for the installation. Installation of Lombok is not required for the deployable war or ear file. It is only required for the specified IDEs. You can download the relevant source that I have explained from the following link "
https://www.dropbox.com/s/uh3ed72mhfvm79y/lombok1.zip". Configure the project in Eclipse and run the Java classes having main methods and you can also go through the javadocs. Lombok provides delombok to generate the original code also. I advise you to use a good decompiler to see the generated code. You can use the JD GUI and have a look into the class and see how the code has been generated and to what extent this framework is useful.
Conclusion
I hope you have enjoyed my small article about the usage of Lombok for Java objects. Download the complete project and go through the source code to understand the concept and its usage. Based on the complexity and design, you can decide whether to use this tool.
References