Java 14 Record vs. Lombok – 爪哇14年对龙目岛的记录

最后修改: 2022年 7月 9日

1. Overview


Java’s record keyword is a new semantic feature introduced in Java 14. Records are very useful for creating small immutable objects. On the other hand, Lombok is a Java library that can auto-generate some known patterns as Java byte-code. Even though both of them can be used to reduce the boilerplate code, they are different tools. Therefore, we should use the one that better suits our needs in a given context.

Java 的记录关键字是 Java 14 中引入的一个新的语义特性。记录对于创建小型不可变的对象非常有用。另一方面,Lombok是一个Java库,可以自动生成一些已知的模式作为Java字节码。尽管它们都可以用来减少模板代码,但它们是不同的工具。因此,我们应该在特定情况下使用更适合我们需求的工具。

In this article, we’ll explore various use-cases, including some limitations of the java records. For each example, we’ll see how Lombok can come in handy and compare the two solutions.


2. Small Immutable Objects


For our first example, we’ll use the Color object. A Color is composed of three integer values which represent the red, green, and blue channels. Furthermore, a color will expose its hex representation. For instance, the color with RGB(255,0,0) will have a hex representation of #FF0000. Besides, we want two colors to be equal if they have the same RGB values.


For these reasons, choosing a record would make perfect sense in this situation:


public record ColorRecord(int red, int green, int blue) {
    public String getHexString() {
        return String.format("#%02X%02X%02X", red, green, blue);

Similarly, Lombok allows us to create immutable objects using the @Value annotation:


public class ColorValueObject {
    int red;
    int green;
    int blue;

    public String getHexString() {
        return String.format("#%02X%02X%02X", red, green, blue);

Nevertheless, starting with Java 14, records will be the natural way for these use-cases.

然而,从Java 14开始,记录将成为这些使用情况的自然方式。

3. Transparent Data Carriers


As per  JDK Enhancement Proposals (JEP 395), Records are classes that act as transparent carriers for immutable data. As a result, we cannot stop a record from exposing its member fields. For instance, we cannot force the ColorRecord from the previous example to only expose the hexString and completely hide the three integer fields.

根据 JDK 增强建议(JEP 395),记录是充当不可变数据的透明载体的类。因此,我们不能阻止一条记录公开其成员字段。例如,我们不能强迫前面例子中的ColorRecord只暴露hexString而完全隐藏三个整数字段。

However, Lombok allows us to customize the names, access levels, and return types of the getters. Let’s update the ColorValueObject accordingly:


public class ColorValueObject {
    int red;
    int green;
    int blue;

    public String getHexString() {
        return String.format("#%02X%02X%02X", red, green, blue);

Consequently, records are a good solution if we need immutable data objects.


However, if we want to hide the member fields and only expose some operations performed using them, Lombok will be better suited.


4. Classes With Many Fields


We’ve seen how records represent a very convenient way of creating small, immutable objects. Let’s see how a record will look if the data model requires more fields. For this example, let’s consider the Student data model:


public record StudentRecord(
  String firstName, 
  String lastName, 
  Long studentId, 
  String email, 
  String phoneNumber, 
  String address, 
  String country, 
  int age) {

We can already guess that the instantiation of StudentRecord will be hard to read and understand, especially if some of the fields aren’t mandatory:


StudentRecord john = new StudentRecord(
  "John", "Doe", null, "", null, null, "England", 20);

To facilitate these use-cases, Lombok provides an implementation of the Builder design pattern.


In order to use it, we simply need to annotate our class with @Builder:


public class StudentBuilder {
    private String firstName;
    private String lastName;
    private Long studentId;
    private String email;
    private String phoneNumber;
    private String address;
    private String country;
    private int age;

Now, let’s use StudentBuilder to create an object with the same attributes:


StudentBuilder john = StudentBuilder.builder()

If we compare the two, we can notice that using the builder pattern is favorable, leading to cleaner code.


In conclusion, records are better for smaller objects. Though, for objects with many fields, the lack of creational patterns will make Lombok’s @Builder a better option.


5. Mutable Data


We can use java records exclusively for immutable data. If the context requires a mutable java object, we can use Lombok’s @Data object instead:


public class ColorData {

    private int red;
    private int green;
    private int blue;

    public String getHexString() {
        return String.format("#%02X%02X%02X", red, green, blue);


Some frameworks may require objects with setters or a default constructor. For instance, Hibernate falls into this category. When creating an @Entity, we’ll have to use Lombok’s annotations or plain Java.


6. Inheritance


Java records do not support inheritance. Therefore, they cannot be extended or inherit other classes. On the other hand, Lombok’s @Value objects can extend other classes, but they are final:


public class MonochromeColor extends ColorData {
    public MonochromeColor(int grayScale) {
        super(grayScale, grayScale, grayScale);

Besides, @Data objects can both extend other classes and be extended. In conclusion, if we need inheritance, we should stick to Lombok’s solutions.


7. Conclusion


In this article, we have seen that Lombok and java records are different tools and serve different purposes. Furthermore, we discovered that Lombok is more flexible, and it can be used for scenarios where records are limited.


As always, the source code is available over on GitHub.