All three can hold data, but they make different promises. A record is a language feature for immutable data with value-based equality. A regular class gives full control. Lombok @Data generates getters, setters, equals, hashCode and toString at compile time, but produces a mutable class and needs an external library.
Key Points: • Record: immutable, final, accessors without "get", equals and hashCode based on all components, no extra instance fields, no library needed. • Regular class: you write everything yourself, can be mutable, can extend other classes and can have any fields. • Lombok @Data: mutable with setters, getX() style getters, works with frameworks that need setters (JPA entities, some mappers). @Value is Lombok's immutable alternative. • Choose a record for DTOs and value objects, Lombok or a regular class for JPA entities and objects whose state changes. • Records work well with Jackson (2.12+) and Spring Boot 3 out of the box.
Code Example:
import java.util.Objects;
public class RecordVsClass {
// One line
record PointRecord(int x, int y) {}
// The equivalent hand-written immutable class
static final class PointClass {
private final int x, y;
PointClass(int x, int y) { this.x = x; this.y = y; }
int x() { return x; }
int y() { return y; }
@Override public boolean equals(Object o) {
return o instanceof PointClass p && p.x == x && p.y == y;
}
@Override public int hashCode() { return Objects.hash(x, y); }
@Override public String toString() { return "PointClass[x=" + x + ", y=" + y + "]"; }
}
public static void main(String[] args) {
System.out.println(new PointRecord(1, 2).equals(new PointRecord(1, 2)));
System.out.println(new PointClass(1, 2).equals(new PointClass(1, 2)));
System.out.println(new PointRecord(1, 2));
System.out.println(new PointClass(1, 2));
}
}Output:
true true PointRecord[x=1, y=2] PointClass[x=1, y=2]
Good to Know: A balanced answer wins here: records remove boilerplate without a library, but they are not a full Lombok replacement. Lombok still helps with builders (@Builder) and mutable classes, and many teams use both.
Interview Tip: A concise interview answer is:
"A record is a built-in, immutable data carrier with value-based equality and no library needed. A regular class gives full control, and Lombok's @Data generates getters, setters, equals and hashCode for a mutable class. I use records for DTOs and value objects, and a regular or Lombok class for entities whose state changes."
Previous question: Can a record have custom constructors, methods and validation?
Next question: What are sealed classes and interfaces in Java 17?