Why Is Lombok Still in Every Java Developer Toolkit?
Why Lombok still holds its respected place amongst experienced Java developers

“Why are you using Lombok to generate getters and setters? I prefer to write them on my own.” — says my coworker and merges the boilerplate getters into the codebase.
Why are developers against Lombok? What are the wrong beliefs they have about Lombok? And why do they prefer to write the boilerplate on their own?
Any tool is deadly if used wrong. One such tool is Lombok. Simple annotation can backfire and cause weird bugs. And this happens only if one abuses Lombok, otherwise it’s a great tool.
Here are some of the misbeliefs I’ve heard about Lombok.
You can trick the compiler using Lombok
@SneakyThrows circumvents the need to handle the checked exception. It’s impossible to have the handlers written without a lot of boilerplate.
This is a hack and trick for the compiler. There’s no counterargument.
Do we really sacrifice so much using this hack? I wouldn’t say so.
With proper error handling up in the call stack, you won’t feel this hack. And on the backend, you get a more readable code that’s easier to consume.
We won’t go into checked exceptions and if they’re evil or not. What Lombok enables us here is to iterate faster. If it’s possible that an exception slips through the cracks, then it’s your concern.
I’ve never had any issues whatsoever with @SneakyThrows. As long as you know what you’re doing.
@SneakyThrows shouldn’t be used to shut up the compiler in every situation. Using SneakyThrows does help when you don’t care about exceptions at that specific place.
You can use Lombok’s obsolete features (are these really obsolete?)
@Value is pointless if you're writing Java 17 or higher.
Records render this annotation obsolete. Even so, we still need Lombok for other annotations.
Hibernate entities benefit greatly from Lombok’s @NoArgsConstructor @Builder and others (avoid @Data though). Lombok is of great help with JPA, and it's certainly a good use case.
You’ll probably use @Builder with records, as there's no native way of building partial records. When withers get implemented for records Builder won't be needed. Until then this is the easiest way of generating partial record builders.
Code generated with Lombok’s @Builder applied to the record.
package com.example.demoslombok;
public record User(String name, String lastName) {
public User(String name, String lastName) {
this.name = name;
this.lastName = lastName;
}
public static User.UserBuilder builder() {
return new User.UserBuilder();
}
public String name() {
return this.name;
}
public String lastName() {
return this.lastName;
}
public static class UserBuilder {
private String name;
private String lastName;
UserBuilder() {
}
public User.UserBuilder name(final String name) {
this.name = name;
return this;
}
public User.UserBuilder lastName(final String lastName) {
this.lastName = lastName;
return this;
}
public User build() {
return new User(this.name, this.lastName);
}
public String toString() {
return "User.UserBuilder(name=" + this.name + ", lastName=" + this.lastName + ")";
}
}
}You don’t @Getter and @Setter for value objects (records).
It’s always better to use records than have Lombok generate them for you. Unless you want mutable objects, records remove all the need for Lombok-generated getters on your custom Java classes.
@Setter is already non-existent for records. Nor will you need it for immutable objects. Every record has a compact construct that suits your needs for immutable objects.
And this is all fine for folks with the pleasure of working with Java 17. But what about those who work with older Java versions?
Most forget that Java upgrades aren’t a non-event in some projects. These features make their Java development easier. So people depend on these features.
Another trait of using Lombok on older codebases, upgrades could wreak havoc. Even though you have delombok, that can backfire in certain use cases.
Here’s a developer’s insight into how delombok doesn’t work as expected:
The urban myth said that moving away from Lombok was a one-step process using delombok to produce the expanded code to replace your annotated files. However, the generated files were extremely ugly and not following any styling, I don’t remember all the problems that we faced. But one example was the use of @NonNull annotations that were converted to many lines using if/throw blocks instead of one-line solutions like Guava Preconditions or Validate from Apache Commons. This should have been expected because makes sense to have the generated code with vanilla Java instead of adding more dependencies, but nobody realizes the real work needed to perform this transition until it’s needed. We ended modifying the implementation of the annotated files instead of using the delomboked files, which was a lot of work. In this situation, many people might prefer to leave Lombok there, but my main concern was what would happen if eventually a migration is really needed to support a major Java upgrade (right now Lombok is still facing problems with Java 9–11), so we preferred to avoid that concern and solve the problem of boilerplate code later.
Use annotations sparingly and where they seem fit. Don’t trust delombok so much as the generated code can be even worse.
You need to know the annotation's inner workings beforehand
Some features of Lombok are forgotten and unused. As an example, Lombok does have withers. But no one heard of them because of the big brother @Builder.
And that’s so for a reason.
@Builder is memory friendlier option than @With.
@Builder isn't related to the number of properties. This annotation only creates the instance of the builder and the instance.
@With creates a new instance for each property. This is a consequence as each intermediate needs to be immutable.
This is just a single example of when annotations can make or break your development experience. But Java as a language evolves to counter these anomalies.
So you won’t even need to learn all of these inner workings. The previous example was record, you now don’t need @Value and you don't care any longer about that annotation.
The same will happen with @With. When withers land we'll forget this annotation. A lot of care is taken to land withers, so they're still not in Java releases.
Lombok can help with the obstacles they’ve faced with this annotation. Discussions around Lombok’s withers are a gold mine for designing Java language features. Or at least they help me understand the problems of withers.
For example, if you look into the comments for the WithBy issue you’ll see the problems Valhalla and Amber will solve. For example, self-referential types, which primitive Valhalla types won’t let happen. And that’s why this problem needs a language solution.





