Fundamentals 7 min read

Master Java 16’s Record Feature in 10 Minutes

This tutorial explains Java 16’s record feature—a concise way to define immutable data carriers—by comparing it with traditional classes, showing the boilerplate it eliminates, detailing the automatically generated methods, providing hands‑on code examples, and outlining important usage considerations.

java1234
java1234
java1234
Master Java 16’s Record Feature in 10 Minutes

What is a record?

Record is a special kind of class introduced in Java 16 to represent immutable data. When you declare a record, the compiler automatically provides a canonical constructor, accessor methods (without the get prefix), equals(), hashCode(), and toString().

What boilerplate does it save compared to a traditional class?

Traditional class example (several dozen lines):

public class Person {
    private final String name;
    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() { return name; }
    public int getAge() { return age; }
    @Override public boolean equals(Object o) { /* ... */ }
    @Override public int hashCode() { /* ... */ }
    @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; }
}

The same functionality with a record:

public record PersonRecord(String name, int age) { }

All the boilerplate code above is generated automatically, reducing dozens of lines to a single declaration.

What does the compiler generate?

Constructor : Parameters correspond one‑to‑one with fields.

Accessor methods : e.g., name(), age() (no get prefix).

equals() / hashCode() : Compare field values.

toString() : Prints all fields, useful for debugging.

Fields are implicitly private final, making the record naturally read‑only.

First record example

public record PersonRecord(String name, int age) {}

public class RecordDemo {
    public static void main(String[] args) {
        // Create an instance
        PersonRecord person = new PersonRecord("张三", 25);
        // Access fields (no <code>get</code> prefix)
        System.out.println(person.name()); // 输出:张三
        System.out.println(person.age());  // 输出:25
        // Auto‑generated toString
        System.out.println(person); // 输出:PersonRecord[name=张三, age=25]
        // Equality check
        PersonRecord another = new PersonRecord("张三", 25);
        System.out.println(person.equals(another)); // 输出:true
    }
}

Common usage examples

As a method return value

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

public class Geometry {
    public static Point getOrigin() {
        return new Point(0, 0);
    }
    public static void main(String[] args) {
        Point origin = getOrigin();
        System.out.println("x=" + origin.x() + ", y=" + origin.y());
    }
}

In collections

import java.util.HashSet;
import java.util.Set;

public record BookRecord(String isbn, String title) {}

public class BookDemo {
    public static void main(String[] args) {
        Set<BookRecord> books = new HashSet<>();
        books.add(new BookRecord("978-001", "Java 入门"));
        books.add(new BookRecord("978-001", "Java 入门")); // duplicate, not added
        System.out.println(books.size()); // 输出:1
    }
}

Custom methods (optional)

public record StudentRecord(String name, int score) {
    // Custom method to check pass/fail
    public boolean isPassed() {
        return score >= 60;
    }
    // Compact constructor for validation
    public StudentRecord {
        if (score < 0 || score > 100) {
            throw new IllegalArgumentException("分数必须在 0~100 之间");
        }
    }
}

Things to watch out for

Suitable for data carriers, not complex business logic. If a class needs mutable state or deep inheritance, a regular class is preferable.

Accessor methods lack the get prefix. Use person.name() instead of person.getName().

Fields are immutable. To modify data you must create a new record instance.

Records cannot extend other classes. They implicitly extend java.lang.Record and may only implement interfaces.

Java version requirement. Records were preview features in Java 14‑15 and became a standard feature starting with Java 16; ensure your JDK version is ≥ 16.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaImmutable DatarecordJava 16Boilerplate Reduction
java1234
Written by

java1234

Former senior programmer at a Fortune Global 500 company, dedicated to sharing Java expertise. Visit Feng's site: Java Knowledge Sharing, www.java1234.com

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.