This article shows how to use the new records feature introduced in java15 and compares it with lombok.
Let’s start with a simple immutable class which holds a couple of private fields.
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:
@Data
public class TransactionLombok {
Records can’t provide mutable object but lombok can with @Data. Therefore lombok will most probably coexist with records for long time.
PS: You can find all the code samples here.