Codectionary / Developer documentation / Java

Records

Introduced as a standard feature in Java 16, a record is a compact way to declare an immutable data-carrier class. Writing 'record Point(int x, int y) {}' automatically generates a constructor, private final fields, public accessor methods, plus equals(), hashCode(), and toString() - all the boilerplate that would otherwise need to be written by hand for a simple immutable class.

Syntax

record RecordName(type field1, type field2) { }

Examples

Basic Record

A record automatically gets a constructor, accessors, equals, hashCode, and toString.

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

public class RecordExample {
    public static void main(String[] args) {
        Point p1 = new Point(3, 4);

        System.out.println(p1.x());          // 3 - auto-generated accessor
        System.out.println(p1.y());          // 4
        System.out.println(p1);               // Point[x=3, y=4] - auto toString()

        Point p2 = new Point(3, 4);
        System.out.println(p1.equals(p2));    // true - auto equals() compares fields
    }
}

Record with Additional Methods

Records can still define their own methods alongside the automatically generated ones.

public record Rectangle(double width, double height) {
    public double area() {
        return width * height;
    }

    public boolean isSquare() {
        return width == height;
    }
}

Rectangle r = new Rectangle(5, 5);
System.out.println(r.area());       // 25.0
System.out.println(r.isSquare());   // true

Compact Constructor for Validation

Records support a compact constructor syntax for validating fields at creation time.

public record Temperature(double celsius) {
    public Temperature {  // compact constructor - no parameter list repeated
        if (celsius < -273.15) {
            throw new IllegalArgumentException("Below absolute zero!");
        }
    }

    public double toFahrenheit() {
        return celsius * 9 / 5 + 32;
    }
}

Temperature t = new Temperature(25);
System.out.println(t.toFahrenheit());  // 77.0

// new Temperature(-300);  // throws IllegalArgumentException

Best practices

  • Use records for simple, immutable data carriers (DTOs, value objects) instead of hand-writing a full class with getters, equals, hashCode, and toString
  • Add validation logic in a compact constructor to guarantee a record can never be created in an invalid state
  • Remember records are implicitly final and all fields are final - they are not meant for classes that need mutable state or inheritance
  • Use a record's auto-generated accessor methods (x(), y()) rather than adding your own getX()/getY() unless you specifically need JavaBean-style naming

At a glance

Purpose
General-purpose application development
File extension
.java
Runs in
Java Virtual Machine
Usually used with
JDK and Java libraries

Specifications & further reading

Related Java documentation

Classes
Classes in Java are blueprints for creating objects, defining their properties (fields) and behaviors (methods). Java is a strictly object-oriented language where everything is encapsulated within classes. A class serves as a template that specifies what data an object will store and what operations it can perform.
Interfaces
An interface defines a contract of methods that implementing classes must provide, without specifying how those methods work internally. Unlike a class, an interface cannot be instantiated directly - it only declares what a class can do, not how. A class uses the 'implements' keyword to fulfill an interface's contract, and a single class can implement multiple interfaces, which is Java's way of achieving a form of multiple inheritance.
Abstract Classes
An abstract class is a class that cannot be instantiated directly and may contain both fully implemented methods and abstract methods (declared without a body, which subclasses must implement). Abstract classes sit between interfaces and regular classes: like an interface, they define a contract; like a regular class, they can hold state (fields) and provide shared, already-implemented behavior.
Constructors
A constructor is a special method that runs automatically when an object is created with 'new', typically used to initialize the object's fields. A constructor shares its name with the class and has no return type, not even void. Java supports constructor overloading, letting a class offer multiple ways to construct an object, and constructor chaining with this(...), where one constructor calls another in the same class.