DZone
Database Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Database Zone > Java Records vs. Lombok

Java Records vs. Lombok

In this article, we will be assessing whether Java Records could replace the Lombok library entirely. Here's what we think.

Gabriel Solano user avatar by
Gabriel Solano
·
Apr. 01, 22 · Database Zone · Opinion
Like (20)
Save
Tweet
14.15K Views

Join the DZone community and get the full member experience.

Join For Free

Java for a lot of time has been accused and mocked for its verbosity. Even the most passionate Java developers have to admit that it felt ridiculous to declare a bean class with two attributes. If you follow the right recommendations, you end up adding not only getters and setters, but also the implementations of toString hashcode and equals methods. The final result is a chunk of boilerplate that invites you to start learning another language. 

Java
 
import java.util.Objects;

public class Car {

   private String brand;
   private String model;
   private int year;

   public String getBrand() {
      return brand;
   }

   public void setBrand(String brand) {
      this.brand = brand;
   }

   public String getModel() {
      return model;
   }

   public void setModel(String model) {
      this.model = model;
   }

   public int getYear() {
      return year;
   }

   public void setYear(int year) {
      this.year = year;
   }

   @Override
   public String toString() {
      return "Car{" +
              "brand='" + brand + '\'' +
              ", model='" + model + '\'' +
              ", year=" + year +
              '}';
   }

   @Override
   public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;
      Car car = (Car) o;
      return year == car.year && Objects.equals(brand, car.brand) && Objects.equals(model, car.model);
   }

   @Override
   public int hashCode() {
      return Objects.hash(brand, model, year);
   }
}


Gratefully, libraries like Lombok came to the rescue and reduced the pain in the eyes of a coder. With the new Java Records feature, one may wonder if it’s OK now to retire Lombok library. Let’s do a short analysis.

What is Lombok?

It’s a Java Library highly integrated with development environments that improve (spice) the code via annotations. It’s highly acceptable and used in the Java community. 

Using Lombok our Car class looks like this:

Java
 
import lombok.Data;

@Data
public class Car {

   private String brand;
   private String model;
   private int year;
}


The code is much cleaner and pleasant to the eyes, without losing any functionality from our previous version.

What Is a Java Record?

A Java record can be shortly described as the implementation of the Value Object pattern. It’s a Java class where all its instances are immutable. Hence, all class attributes need to be passed during object creation. It was introduced in Java 14 and it is almost sure that it will continue evolving to improve class design.

The Car class as a record looks like this:

Java
 
public record Car(String brand, String model, int year) {
   
}

It's also a huge improvement from our first version. But let's analyze a few aspects of Lombok and compare them to records to assess if we're ready to give permanent vacations to our spicy friend. 

Immutability

Records are by default immutable. That means that all class attributes are declared implicitly as final. We can say they are like ValueObjects. They don’t have setter methods and all their values need to be passed in the constructor. Lombok can do the same using the @Value annotation, but can also preserve the mutability using just the @Data annotation.

Java
 
import lombok.Value;

@Value
public class Car {

   private String brand;
   private String model;
   private int year;
}


Bean Convention

Records are not meant to be compliant with bean conventions. The accessor methods are not named with getX and the class does not provide setters nor a no-args constructor. For Lombok on the other hand, simply using the @Data annotation can convert a class into a Java Bean.

Builders

The builder pattern is a great design pattern to improve our object creation syntax. Lombok provides a convenient annotation that implements for us all the boilerplate code of this pattern. Java Records do not intend to provide this implementation (for now).

Java
 
import lombok.Builder;

@Builder
public class Car {

   private String brand;
   private String model;
   private int year;

   public static void main(String[] args) {
      Car myCamaro = Car.builder()
              .brand("Chevrolet")
              .model("Camaro")
              .year(2022)
              .build();
   }
}


Big Classes

Records look good with a few fields. But add 10 fields to them and you will end up with a monster of a constructor with all the intrinsic problems of big constructors. 

Java
 
public record DetailedCar(
  String brand, String model, int year,
  String engineCode, String engineType, String requiredFuel,
  String fuelSystem, String maxHorsePower, String maxTorque, 
  float fuelCapacity) {
}
Java
 
DetailedCar camaroDetailed = new DetailedCar(
  "Chevrolet", "Camaro", 2022, "LTG", "Turbocharged",
  "Gas I4", "Direct Injection", "275 @ 560", "295 @ 3000-4500", 
  19.0f);

Using Lombok we could decide to leave the class as a bean having to option to use setters to set the state of the object or use a builder to have a cleaner way to construct the instance. The only caveat is that we could leave the instance in an incomplete state by not forcing all attributes to be set. In the case of the Builder annotation, we can mark all the class attributes as @nonNull making them all required when building it. But this would throw an error at runtime, versus forcing a compilation error with records.

Java
 
import lombok.Builder;
import lombok.NonNull;

@Builder
public class DetailedCar {
   @NonNull
   private String brand;
   @NonNull
   private String model;
   @NonNull
   private int year;
   @NonNull
   private String engineCode;
   @NonNull
   private String engineType;
   @NonNull
   private String requiredFuel;
   @NonNull
   private String fuelSystem;
   @NonNull
   private String maxHorsePower;
   @NonNull
   private String maxTorque;
   @NonNull
   private float fuelCapacity;

   public static void main(String[] args) {
      DetailedCar camaroIncomplete = DetailedCar.builder()
              .brand("Chevrolet")
              .model("Camaro")
              .year(2022)
              .build();
   }
}

Output:

Exception in thread "main" java.lang.NullPointerException: engineCode is marked non-null but is null

Inheritance

Java record classes, as of this moment, do not support inheritance. You cannot make a record class extend another record class. This could be a limitation to model designing. Although, we all had learned that we should favor composition over inheritance. 

Lombok annotations can be parametrized to consider parent class attributes in toString/hashcode/equals methods.

Java
 
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class Car extends MotorVehicle {

   private String brand;
   private String model;
   private int year;
   
}


Conclusion

Java records are a great new feature of the language, moving in the right direction of cleaner code. We should start using them whenever there is an opportunity. But given the great versatility of Lombok library, and the slow (but surely) pace of Java language changes, it looks like it's too early to remove the Lombok dependency from our projects. 

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 4 Careers for People with Coding Backgrounds
  • Top ALM Tools and Solutions Providers
  • Delegating JWT Validation for Greater Flexibility
  • Anypoint CLI Commands in MuleSoft

Comments

Database Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo