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

20 thoughts on “Project Lombok- Now write less boilerplate code in Java”

  1. Started using this in my company and the one downside with it is that it does not generate javadoc for the getters/setters. Had to throw it out again because of this.

    Reply
  2. Very nicely explained.
    The example is simple but does its job.

    @Mohamed Sanaulla:
    Though Project Lombok has some nice ideas, I would like to emphasize that the core language needs to be clear, concise, unambiguous, extensible etc. It needs to flexible enough to allow libraries such as these to evolve on it. Doesn’t necessarily need to contain everything itself 🙂

    Reply
    • Agree with your point. But the features going into Java go through JCP and its always a long process before a feature gets approved and then implemented in the language.

      I feel that Java has to reduce the boilerplate code we write. At times its so boring to write these getters and setters just for the sake of information hiding.

      Reply
      • I disagree at least at one point. We donot need to writter Getter & Setter by hand. Eclipse (i donot know if other IDEs does this too) do it for us. it is just a click away. And same is about contructor. We can generate from no arg to all argument constructor with eclipse. Just to spare this work adding another annotation in my opinion not correct. Look how many annotation does class contain these days

        @Entity
        @Table(name = “ABC_TABLE”)
        @AttributeOverride(name = “abc”, column = @Column(name = “YXYZ”, length = “10”)
        @NoArgsConstructor
        @AllArgsConstructor
        @Getter
        @Setter

      • Yes with almost all the IDEs such refactoring is supported. There are quite a good percentage of people still using Emacs and Vim so they might not get such advanced IDE features.
        But to be frank, all those functionalities which requires external jars are not very easily adopted by companies as they would say that such features are good to have and not really necessary to add a 3rd party jar.

  3. What make me launch is that instead of just not implements getters/setter at all and in fact remove the boiler plate code, on want to keep it and auto generate it.

    If you have real logic in an object, is it a bad design to add getters & setters. For objects with behaviour is better to hide it’s interval state anyway.

    No, when we think of POJO and getters & setter, we don’t speak about complexs algorythms. We think about Value Objects, or DTO. Something that could very well fit into a Map. Something that will be serialised to a database or an XML file anyway.

    It has no behaviour. It is just a C struct.

    Let see how this would look :

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

    Isn’t it simpler ? No annotation, no getter, no setter, no constructor.

    And then everybody start to say that it violate encapusation. You are right. But we all know that your framework give you a copy of the object, not the real value (that is stored in database). Indeed, many design even use two or 3 POJO : One for the UI layer, One for the business layer, on for the dataaccess layer.

    Your UI layer create new objects anyway and have under control all the field value. It use a constructor or a setter. Wow that make your day. But it still change the value of the field.

    Your dataaccess make a copy of the object before giving it to the business layer anyway. And hibernate will throw you exception if you try to modify a DTO outside of the a transaction… So…

    You want a C struct, you need a C struct. But you can’t resist to add setters/getters and all. You don’t even know why. Or yes : it is in case you need to add some logic in the getter or setter.

    Just wondering, can you remember the last time you have done that ? What is legetimate ? Was it a good fit and a good pratice for the framework you were using ?

    Reply
    • In principle I agree with you. For most of the time POJO-s are used as structs.

      But there are at least 2 reasons why I do not adore this practice:
      1) suppport – there are lots of libraries which demand getters and setters and do not work with fields

      2) In swing or multithreaded code there are legimite reasons why one would add logic to setters/getters latter on. Casses slike add PropertyChangeSupport, syncronize on write or quit-early-if-value-blocked cases…

      Reply
  4. I also looked at Project Lombok but deemed it too risky to use (f.x. there are issues with the latest JDK). I also found the customisation features lacking, so I just released my own open source tool for generating java value objects that used 100% standard java features and is extremely customisable. You can check it out at “http://valjogen.41concepts.com”. Let me know what you think?

    Reply

Leave a Reply

Discover more from Experiences Unlimited

Subscribe now to keep reading and get access to the full archive.

Continue reading