Site icon Experiences Unlimited

Project Lombok- Now write less boilerplate code in Java

We, Java Programmers, are tired of writing- Getters, Setters, Constructors, and other boilerplate code or tired of reading this boilerplate code. Often the important logic in the class gets hidden due to these boilerplate code. May be in the coming JDK versions we might have an alternative for these boilerplate code. But till then we have an alternative- Project Lombok which processes the special annotations while you are still writing the code, which means that while you are developing your application- You still have an access to the Getters and Setters or other boilerplate code which is generated by this library. But it comes with its own set of dependencies-  Firstly, its dependent on IDE and  the JDK versions to generate the boilerplate code and to parse the annotations. Secondly, it requires an external JAR to be used. Also people reading the code might not be familiar with the Annotations being used or about Lombok. Though its not hard to learn and with documentation of the code- the person should be able to identify the annotations. Let me take a simple Class- Employee and see how we can use Lombok to make our coding simpler(at least readable to some extent).

Also the Lombok API is well integrated into Netbeans, Eclipse IDEs. So you can download the jar from the site and run the jar to choose which IDE to integrate with Lombok.

This is how one would write a Java class(Java bean) under normal circumstances:

public class Employee
{
  private String firstName;
  private String lastName;
  private int id;
  private int age;

  public Employee(){}
  //Overloaded constructor taking the parameters

  public String getFirstName(){ return this.firstName;}
  public void setFirstName(String fName){ firstName=fName;}
  //And so on for other properties. ...
  //This would generate a huge code.

}

Now lets use Lombok to help us out.(I am using Netbeans 6.9). Firstly lets get rid of these getters and setters.
Using @Getters and @Setters:

public class Employee
{
  @Getter @Setter private String firstName;
  @Getter @Setter private String lastName;
  @Getter private int id;
  @Getter @Setter(AccessLevel.PRIVATE) private int age;
}

One can even pass the access level for the methods being generated. One advantage I would like to add here is- Suppose I happened to change the name of the one of the attributes or all of the attributes- I need not worry to change the getters and setters as they are generated again depending on the new name, removing the old methods.

Now lets see how we can add the constructors- The default(No-Arg Constructor), constructor for all the member fields and for those fields which require initialization- Like final. For this we make use of the annotations:
@NoArgsConstructor– Gives the No Arg Constructor (useful when you are providing overloaded constructors)
@AllArgsConstructor– Constructor which takes all the member fields as the parameters.
@RequiredArgsConstructor– Constructor which takes only the fields which require initialization- like Final fields.
Lets take a look at an example:

@NoArgsConstructor
@AllArgsConstructor
public class Employee
{
  @Getter @Setter private String firstName;
  @Getter @Setter private String lastName;
  @Getter private int id;
  @Getter @Setter(AccessLevel.PRIVATE) private int age;
}

Using @ToString will override the toString() method and the default implementation- name-value pairs for the fields of that instance, which is really useful when we are just trying to look at the contents of the instance. @EqualsAndHashCode generates- equals and hashCode methods. And the good thing about the equals method is that it does check the contents of the instances to see if they are equal and not just checking if they point to the same instance.

Then there is @Data annotation which does the job of- @Getters, @Setters, @ToString, @EqualsAndHashCode. Lets look at an example to see how these work:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Employee {
  private String firstName;
  private String lastName;
  private int id;
  public static void main(String[] args)
  {
    Employee emp1 = new Employee("Mohamed", "Sanaulla", 1);
    Employee emp2 = new Employee("Mohamed", "Sanaulla", 2);
    Employee emp3 = new Employee("Mohamed", "Sanaulla", 1);
    System.out.println(emp1);
    System.out.println(emp2);
    System.out.println(emp1.equals(emp2));
    System.out.println(emp1.equals(emp3));
  }
}

Output for the above program:

run:
Employee(firstName=Mohamed, lastName=Sanaulla, id=1)
Employee(firstName=Mohamed, lastName=Sanaulla, id=2)
false
true
BUILD SUCCESSFUL (total time: 2 seconds)

Note: You would have to add import lombok.*; to import the corresponding definitions. There are other annotations as well like – @Cleanup, @Synchronized. I didn’t find them much useful. One can read about them from the project site. @Cleanup is kind of really good one- it does provide the closing of the resources with a try …finally. But in cases where there are exceptions thrown- we would still have to enclose that code with in the try catch- there by we would have 2 try .. catch nested within each other. Also these generated code provide the default implementations- like for example- you wanted to do some extra checks while setting the data- you can always provide your own setters and also use these annotations simultaneously.

Update: There was a query on how Javadoc can be generated for the Annotated code and we had Roel Spilker(One of the creators of Lombok) replying to the comment that javadoc can be generated by using delombok. One can read about it here (at the end of the page).

Exit mobile version