Java Tutorial · Object-Oriented Java · Lesson 24 of 37

Java Records

Immutable data classes in one line with records (Java 16+).

What is a record?

A record is a concise, immutable data class. From one line, Java generates the constructor, accessor methods, equals(), hashCode() and toString():

Example 1
public class Main {
    public static void main(String[] args) {
        Person a = new Person("Ada", 36);
        Person b = new Person("Ada", 36);
        System.out.println(a);
        System.out.println(a.name() + " is " + a.age());
        System.out.println(a.equals(b) + " " + (a.hashCode() == b.hashCode()));
    }

    record Person(String name, int age) {}
}

Output

Person[name=Ada, age=36]
Ada is 36
true true

Run this on your computer — see “Get Started” for setup.

Accessors are named after the fields — p.name(), not getName().

Validation and extra methods

A compact constructor validates or normalises the values; you can add methods and static factories too:

Example 2
public class Main {
    public static void main(String[] args) {
        Money price = new Money(1999, "usd");
        Money total = price.times(3);
        System.out.println(price + " -> " + total.format());
        try {
            new Money(-5, "USD");
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }
    }

    record Money(long cents, String currency) {
        Money {
            if (cents < 0) throw new IllegalArgumentException("cents must be >= 0");
            currency = currency.toUpperCase();
        }

        Money times(int qty) {
            return new Money(cents * qty, currency);
        }

        String format() {
            return String.format("%d.%02d %s", cents / 100, cents % 100, currency);
        }
    }
}

Output

Money[cents=1999, currency=USD] -> 59.97 USD
cents must be >= 0

Run this on your computer — see “Get Started” for setup.

Records are perfect for DTOs, API responses, map keys and values returned from methods.

Test yourself

What is the accessor for a record component name?

  1. getName()
  2. name()
  3. name
  4. get("name")
Show answer

Answer: name()

Practice next