Record

A record is a compact class syntax for immutable data carriers, stabilised in Java 16. One line replaces 30 lines of POJO boilerplate — the compiler generates the canonical constructor, accessors, equals, hashCode and toString automatically.

Declaration and use

public record Point(int x, int y) {}

Point p = new Point(3, 4);
System.out.println(p.x());           // 3 — accessor named after the component
System.out.println(p);                // Point[x=3, y=4]
System.out.println(p.equals(new Point(3, 4))); // true

Custom methods and validation

public record Range(int min, int max) {
    public Range {
        // compact constructor — runs after parameter assignment
        if (min > max) throw new IllegalArgumentException("min > max");
    }

    public int length() { return max - min; }
}

Records are classes

A record can implement interfaces, have static methods and fields, have private methods. It cannot extend another class (always extends java.lang.Record implicitly) and its components are always final.

When to use records

  • DTOs and API payloads (JSON serialisation, Jackson supports records natively).
  • Tuple-like return types.
  • Pattern matching targets (records pair especially well with sealed classes and pattern matching in switch).
  • Map keys (records get a sensible hashCode/equals for free).

When not to

If you need mutability, setters, or framework behaviour that requires a no-arg constructor (older JPA versions), stick with a regular class.