Write Precise Java Code With LOMBOK

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 the functionalities whether they are simple or complex. In the 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;

 

/**

 * The Class NonNullCheck is used to provide an example on the generation of

 * NullPointerException with the help of Lombok @NonNull annotation.

 *

 * @author <a href="mailto:[email protected]">Debadatta Mishra</a>

 * @since 2013

 */

public class NonNullCheck

{

 

    /** The value. */

    @NonNull

    private String value;

 

    /**

    * Instantiates a new non null check.    

    * @param value

    * the value

    */

    public NonNullCheck(@NonNull String value) {

    this.value = value;

    }

    /**

    * Show.

    */

     public void show()

     {

         System.out.println("Value--->" + value);

     }

 

      /**

      * The main method.

      *

      * @param args

      * the arguments

      */

      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;

 

/**

 * The Class FileReader is used as utility to read a file by minimizing the

 * code. In this class @NonNull and @Cleanup annontations have been used for

 * null check and close operations respectively.

 *

 * @author <a href="mailto:[email protected]">Debadatta Mishra</a>

 * @since 2013

 */

public class FileReader {

 

    /**

    * Read file.    

    * @NonNull annotation will generate a NullPointerException code at runtime

    * @Cleanup annotation will generate the close() method at run time

    * @param filePath

    * the file path

    * @throws Exception

    * the exception

    */

     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));

     }

 

     /**

     * The main method.     

     * @param args

     * the arguments

     */

     public static void main(String[] args) {

     try {

              FileReader.readFile("data/data.txt");

              //FileReader.readFile(null);

     } 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;

 

/**

 * The Class Employee is used as a POJO for employee having id and name. Lombok

 * annotation will generate all the getter and setter methods for properties.

 *

 * @author <a href="mailto:[email protected]">Debadatta Mishra</a>

 * @since 2013

 */

public class Employee {

 

   /**

   * Specifies the id of the employee.

   *

   * @Getter annotation will generate all the getter method for id.

   * @Setter annotation will generate all the setter method for id.

   */

    @Getter

    @Setter

    private int id;

 

    /**

    * Specifies the name.

    *

    * @Getter annotation will generate all the getter method for name.

    * @Setter annotation will generate all the setter method for name.

    */

    @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;

 

/**

 * The Class Student is used to provide the usage of Lombok annotation for the

 * methods toString() , equals() and hashcode().

 *

 * @author <a href="mailto:[email protected]">Debadatta Mishra</a>

 * @since 2013

 */

 

@ToString

@EqualsAndHashCode

public class Student {

 

    /** Gets the roll no. */ 

    /**

    * Gets the roll no.

    *

    * @return the roll no

    */

    @Getter

    /**

    * Sets the roll no.

    *

    * @param rollNo the new roll no

    */

    /**

    * Sets the roll no.

    *

    * @param rollNo the new roll no

    */

    @Setter

    private int rollNo;

 

    /** Gets the name. */

     /**

     * Gets the name.

     *

     * @return the name

     */

     @Getter

     /**

     * Sets the name.

     *

     * @param name the new name

     */

     /**

     * Sets the name.

     *

     * @param name the new name

     */

     @Setter

     private String name;

 

     /**

     * Instantiates a new student.

     *

     * @param rollNo

     *            the roll no

     * @param name

     * the 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;

 

/**

 * Instantiates a new person. This class provides the usage of @Data lombok

 * annotation to generate getter, setter, toString, hashcode and equals methods.

 *

 */

@Data

public class Person {

 

   /** The id. */

   private int id;

 

   /** The name. */

   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;

 

/**

 * Instantiates a new immutable employee. * {@value} annotation is used to

 * convert the class into an immutable class.

 *

 * @param id

 *            the id

 * @param name

 *            the name

 * @param dateOfBirth

 *            the date of birth

 */

@Value

public class ImmutableEmployee {

 

      /** The id. */

      private int id;

 

      /** The name. */

      private String name;

 

      /**

       * Do not use Date type object, it will not give correct implementation of

       * immutable flavour, rather use date of birth as String type.

       */

      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;

 

/**

 * The Class UseOfVal is used to provide the usage of Lombok annotation val for

 * the final generic type.

 *

 * @author <a href="mailto:[email protected]">Debadatta Mishra</a>

 * @since 2013

 */

public class UseOfVal {

 

   /**

   * Populate names.

   *

   * @param names

   * the names

   */

   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;

 

/**

 * This class is used as demo for slf4j.

 *

 * @author Debadatta Mishra (PIKU)

 */

@Log4j

public class TestLog4jLogger {

    /**

    * This method is used to display the varous logger messages.

    */

    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.

http://projectlombok.org/

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 upon the complexity and design, you can decide whether to use this tool.

References

http://projectlombok.org/
https://www.dropbox.com/s/uh3ed72mhfvm79y/lombok1.zip
http://projectlombok.org/api/index.html

Up Next
    Ebook Download
    View all
    Learn
    View all