How to write less and better code, or Project Lombok

I have long intended to write about Project Lombok, so much so that I am probably doing it when every self-respecting Java developer has already heard about it. Nevertheless, it is worth mentioning, if only to remind myself that one should not hesitate to try performance-enhancing tools and see if they fit, and Lombok is certainly enhancing performance of a Java-coder by allowing to simultaneously write less code and add to its quality, which is no small matter.
What is it that Java opponents usually say about its weaknesses?
Java is too verbose.
© Every Java opponent
Unfortunately, there’s a lot of truth in this statement. Imagine a simple data class you want to have to store the personal information — name, age etc. It might look like this.
OK, you say. I generated all this stuff with the IDE, wasn’t that hard. But we also need a hashCode() and equals(). Because you might want to keep the instances in collections and check equality. No problem, most IDEs will allow you to generate these as well as getters and setters. And they will throw in a toString() generator to help you output the objects and see what’s in them.
OK then. All this stuff was generated by IntelliJ IDEA. It is not that difficult right? Well no. But now you are thinking of Josh Bloch and decide to apply a Builder pattern. This time, you have to do a little manual work. What you will likely have in the end will be something close to this.
So. We have a builder, and now our PersonSimple can be created with a piece of code like this.
But you had to create so many things. You have:
- a data class with an all-arguments private constructor;
- three getters on a data class;
- an accompanying builder class with three setters;
- a build() method on a builder class that calls the private data class constructor;
- and don’t forget the hashCode(), equals() and toString() methods, though generated.
The code now takes more than 70 lines. And every time you need a new field, you will have to take care of it in at least three places — getter in the data class, setter in the builder class, and the constructor.
What if I were to show you how to do the same things with Project Lombok?
OK, here goes.
- We generated the builder class with @Builder annotation. toBuilder=true means that we additionally created a toBuilder() instance method that creates a new instance of the builder class, initialized with the values from the current instance.
- We added a toString() method with a @ToString annotation.
- We added hashCode() and equals() with, you guessed it, @EqualsAndHashCode.
- We made the all-argument constructor private with @AllArgsConstructor(access = AccessLevel.PRIVATE).
- We added standard getters to the class fields with @Getter annotations.
It is now fifteen lines of code. Fifteen! We just decreased the code five times. The gain would be even better for a class with a lot of fields.
So, what exactly does Project Lombok do? It generates all the boilerplate during compile time, allowing you to avoid writing that code manually or generating it with an IDE. It saves you a lot of time and allows to create prettier code with less effort.
After the lombokization of your code, the person can be created like this.
To add Lombok to your project, you need to add a dependency for it and also in my case install a Lombok plugin for IDEA. The Gradle configuration is described here and maven here.
All the features of Lombok are described here. Please have a look and see if there’s anything else that might come in useful, because what I described here is just a small part of what it has.
The code from examples is stored in my github repository. Article also was originally posted on my personal blog here.
I wish you clean and concise code!