What are Java records, and what problem do they solve?

8 minintermediaterecordsjava16immutability

Quick Answer

Records (Java 16+) are a concise way to declare immutable data-carrier classes: from a single declaration, the compiler generates a canonical constructor, private final fields, public accessors, and correct equals()/hashCode()/toString(). They eliminate the verbose, error-prone boilerplate of hand-written value/DTO classes.

Detailed Answer

Before records, a simple immutable data holder required a lot of repetitive, error-prone boilerplate: private final fields, a constructor, getters, and manually-written equals()/hashCode()/toString() — easy to get subtly wrong (e.g., forgetting a field in equals()).

A record (finalized in Java 16) collapses all of that into one declaration:

record Point(int x, int y) { }

This single line generates:

  • private final int x; private final int y;
  • A canonical constructor Point(int x, int y)
  • Accessor methods x() and y() (not getX() — no "get" prefix)
  • Correct, component-based equals(), hashCode(), and toString()

Records can still have additional methods, static members, and a compact constructor for validation:

record Range(int min, int max) {
    Range { // compact constructor — validates before fields are assigned
        if (min > max) throw new IllegalArgumentException("min > max");
    }
    int length() { return max - min; }
}

Constraints: all fields are implicitly private final, a record cannot extend another class (it implicitly extends Record), and it cannot declare additional instance fields beyond its components. Records are ideal for DTOs, value objects, and API response/request shapes — anywhere you want a transparent, immutable carrier of data without hand-rolling boilerplate.

Related Resources