What is the difference between a record, a regular class and a Lombok @Data class?

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?

More Java 17 and 21 Features interview questions

All Java 17 and 21 Features questions