Immutability with Lombok builder pattern

Lombok builder gives minimalistic code

Lombok is a tool that makes it possible to write classes in Java the way it is supposed to. It reduces a lot of the boilerplate code required that many modern languages already have built-in support for, such as Golang and Kotlin. Lombok supports the traditional OOP class structure with getters and setters, but my favorite part is the Lombok Builder which enables us to write immutable classes with almost no code required at all. In this article, we are going to explore that and hopefully, you will be convinced and start using it yourself.

If you have been following my previous blogs, you might already know that I am a big advocate of immutable objects, it has tons of benefits, as you can read about more in detail in my previous article Achieve thread-safety with immutability. However, one of the downsides of the builder pattern is that it requires a lot more boilerplate code to get started (although, in my opinion, it is totally worth it). But wouldn’t it be nice if we could get all the good stuff that comes from immutability with the builder pattern, but at the same time don’t require so much boilerplate code? Well, with Lombok it is actually totally possible!

Maven dependency

We only need one dependency to get started with Lombok.

Lombok builder

Let’s create an example class. My class represents a Person that has a name, an age and lives in a city. The person may also have children and a car.

That’s all the code required for our immutable person class with the builder pattern, isn’t that awesome?! The @Builder annotation is the key here. With that annotation, it becomes possible to create a person like the following.

However, there isn’t that much that we can do with that person without adding a couple of more annotations such as; @Getter which adds getters for all of our fields, @ToString which generates a nice toString() with all of our fields.

Additionally, I have annotated some fields with @NonNull which will perform a null check in the constructor, and throw a NullPointerException when attempting to create an object with a not allowed null value. Personally, I would have preferred a IllegalArgumentException but if that is important for you, then you can simply override the constructor, creating a private one that takes all the arguments and where you can check for null and other values that you don’t want to allow.

Comparison

If we were to create the above class above manually, it would be a lot of boilerplate code and it would look something similar to the following.

Around 100 more lines of code required to do the exact same thing, that’s a huge difference! As a lazy developer (which most of us are by nature), you gotta love that.

Testing the Lombok builder class

I’m sure we all can agree that Lombok looks nice in theory, but let’s get practical and put it to test to make sure that it works. I wrote a couple of JUnit tests that can be seen below.

Other handy Lombok annotation

There are tons of more handy Lombok annotations such as @EqualsAndHashCode to generate an equals and hashcode with all of your fields, and @Synchronized which doesn’t expose your locks. I recommend checking out Project Lombok for additional features.

Final words

This was a quick introduction to Lombok, and more specifically the Lombok Builder. After discovering Lombok, it is hard to go back to plain old Java classes, and why should you? You will save tons of time from not wasting it on writing boilerplate code.

The only true downside that I see to Lombok is that all of your team members will need to enable it in their IDEA, or they will see lots of errors. But that’s the only real downside that I can see to it, of course, there are minor stuff such as @NonNull returning a NullPointerException instead of a IllegalArgumentException, but small stuff like that is easily worth to put up with when you get to skip writing boring boilerplate code.

Additionally, even though you add annotations, for example @Getter that doesn’t prevent you from still creating a custom getter for certain fields. Let’s say that you want to make use of Java 8 Optional, if you simply create a getter like the following:

It then it overrides the getter that Lombok was going to create for you. Which is very convenient since it will make it a lot easier to start implementing Lombok in your project, but still maintain some custom stuff that you require.

You may also like

Leave a Reply

Your email address will not be published. Required fields are marked *