Future Of Lombok
Tags: discuss, java, lombook
Published: 2021-03-25 07:06:54

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;
}
```

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);
```

Records way
Define a record:
```
record TransactionRecord(String from, String to, int amount) {
}
```

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);
```

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]");
```

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 {
```

Or just make it a value:

```
@Value
public class TransactionLombok {
```

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);
}
```

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

```
public TransactionRecord {
    Objects.requireNonNull(from);
    Objects.requireNonNull(to);
}
```


*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 {
```
Records just don’t provide builder and clone functions. Therefore lombok will most probably coexist with records for long time.