DEV Community

Gaurav
Gaurav

Posted on • Edited on

Future Of Lombok

Following the general release of JDK 16: https://jdk.java.net/16/ and
specially https://openjdk.java.net/jeps/396 Lombok has severe build
issues due to its reliance on the JDK internals which 16 has closed off,
discussion here:
https://github.com/rzwitserloot/lombok/issues/2681

Given the fact that Java 16 brings Records out of preview and libs like
Lombok (over)relying on internal JDK functions, does it make sense to
use Lombok in our code anymore?

Java Records don't require any additional dependency, so it's better to use them instead of Lombok I think.

If your project supports Java 14 you can already use them in Eclipse.
There's a plugin in the marketplace for it:

https://marketplace.eclipse.org/content/java-14-support-eclipse-2020-03-415

Lombok way
Add lombok annotations on top of the class:

import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public class TransactionLombok {
    private final String from;
    private final String to;
    private final int amount;
}
Enter fullscreen mode Exit fullscreen mode

A constructor with all arguments and getters are generated by lombok.

TransactionLombok transactionLombok = new TransactionLombok("you", "me", 100);
assertThat(transactionLombok.getFrom()).isEqualTo("you");
assertThat(transactionLombok.getTo()).isEqualTo("me");
assertThat(transactionLombok.getAmount()).isEqualTo(100);
Enter fullscreen mode Exit fullscreen mode

Records way
Define a record:

record TransactionRecord(String from, String to, int amount) {
}
Enter fullscreen mode Exit fullscreen mode

You get constructor and getters by default in a record:

TransactionRecord transactionRecord = new TransactionRecord("you", "me", 100);
assertThat(transactionRecord.from()).isEqualTo("you");
assertThat(transactionRecord.to()).isEqualTo("me");
assertThat(transactionRecord.amount()).isEqualTo(100);
Enter fullscreen mode Exit fullscreen mode

As we can see the new record keyword does the same job in a much neater way.
Anything more?
Yes, records can do more than that. It also provides the equals, hashCode and toString automatically for you. So this works as well.

assertThat(transactionRecord.equals(anotherTransactionRecord)).isTrue();
assertThat(transactionRecord.hashCode()).isEqualTo(anotherTransactionRecord.hashCode());
assertThat(transactionRecord.toString()).isEqualTo("TransactionRecord[from=you, to=me, amount=100]");
Enter fullscreen mode Exit fullscreen mode

While in lombok you have to achieve the same thing by adding a few more annotations like this:

@ToString
@EqualsAndHashCode
@AllArgsConstructor
@Getter
public class TransactionLombok {
Enter fullscreen mode Exit fullscreen mode

Or just make it a value:

@Value
public class TransactionLombok {
Enter fullscreen mode Exit fullscreen mode

So the record keyword can be considered as an equivalent to lombok’s @Value annotation.
Customized constructor
In addition, records also supports customized constructors like this:

public TransactionRecord(String from, String to) {
    this(from, to, 0);
}
Enter fullscreen mode Exit fullscreen mode

And if you want to validate the arguments, it’s also possible:

public TransactionRecord {
    Objects.requireNonNull(from);
    Objects.requireNonNull(to);
}
Enter fullscreen mode Exit fullscreen mode

Can records replace lombok?
No.

Even though records provides a lot of nice features and is neat in code, lombok still has way more features than records. For example:

@Builder
@With
public class TransactionLombok {
Enter fullscreen mode Exit fullscreen mode

Records just don’t provide builder and clone functions. Therefore lombok will most probably coexist with records for long time.

Top comments (0)