Blog

Wie Sie Java Records verwenden

David Hoepelman

David Hoepelman

Aktualisiert Oktober 16, 2025
4 Minuten

Datensätze in Java (3-teilige Serie)

  1. Was sind Java-Datensätze?
  2. Wie Sie Java Records verwenden
  3. Java-Datensätze als Datentransfer-Objekte (demnächst)

Inhaltsverzeichnis

Java-Datensätze erstellen und verwenden

Die Verwendung eines Java-Datensatzes ist fast genauso wie die Verwendung eines unveränderlichen POJO.
Die Erstellung eines solchen Datensatzes erfolgt mit dem Konstruktor:

record Customer(UUID id, String name) {}
var customer = new Customer(UUID.randomUUID(), "John");

Das Abrufen der Daten erfolgt nach wie vor über Getter-Methoden, die denselben Namen wie die Datensatzkomponenten haben.
Beachten Sie, dass die JavaBean-Konventionen nicht verwendet werden, so dass ein Getter x() und nicht getX() heißt:

var name = customer.name();

Dokumentation

Die Dokumentation für Java-Datensätze kann wie bei einer Klasse hinzugefügt werden. Eine Komponente kann mit dem vorhandenen Code dokumentiert werden >@param javadoc tag:

/**
* Documentation of the Customer class.
* @param id customer id
* @param name customer name
*/
record Customer(UUID id, String name) {}

Standardwerte

Datensätze können neben ihrem kanonischen Konstruktor, der die gleichen Parameter wie die Komponenten hat, zusätzliche Konstruktoren haben.
Dies kann nützlich sein, um Standardwerte für einige Komponenten festzulegen.

record Customer(UUID id, String name) {
    /** Create a new customer with a fresh id. */
    public Customer(String name) {
        this(UUID.randomUUID(), name);
    }
}

var customer = new Customer("John");
UUID generated = customer.id();

Validierung

Oftmals möchten Sie nicht alle Werte in einer Datensatzkomponente zulassen, sondern sie auf das beschränken, was im Kontext dessen, was Ihr Datensatz darstellt, sinnvoll ist.

Records bieten ein spezielles Konstrukt, den so genannten kompakten Konstruktor, um dies zu erleichtern.
Sie funktionieren ähnlich wie ein normaler Konstruktor, aber Sie müssen keine Parameter angeben oder die Komponenten festlegen:

record Customer(UUID id, String name) {
    public Customer {
        if(name.isBlank()) {
          throw new IllegalArgumentException("name cannot be empty.");
        }
    }
}

// This will throw an IllegalArgumentException 
var invalidCustomer = new Customer(UUID.randomUUID(), " ");

Normalisierung

Neben der Validierung können Sie auch Daten in einem kompakten Konstruktor ändern.
Dies ist nützlich, um Ihre Daten zu normalisieren:

record Customer(UUID id, String name) {
    Customer {
        name = name.trim();
    }
}

Customer customer = new Customer(UUID.randomUUID(), "John n");
// This will be "John"
String name = customer.name();

Ändern von java java recordrecords

Leider sind Datensätze nicht so einfach zu ändern wie ihre Äquivalente in anderen Sprachen.
Derzeit gibt es zwei praktikable Möglichkeiten, Datensätze zu ändern. Eine zukünftige Version von Java könnte diesen Anwendungsfall besser unterstützen.

Option 1 - Manuelles Hinzufügen von Verwelkungsmethoden

In einfachem Java können Sie manuell eine Methode angeben, die eine geänderte Kopie zurückgibt.
Die gebräuchlichste Namenskonvention dafür ist withX, daher der Name Wither-Methoden.

record Customer(UUID id, String name) {
    Customer withName(String name) {
        return new Customer(id, name);
    }
}

var customer = new Customer(UUID.randomUUID(), "John");
var renamed = customer.withName("John Doe");

Option 2 - Verwenden Sie ein Compiler-Plugin

Das ist nicht besonders benutzerfreundlich.
Glücklicherweise können Compiler-Plugins die fehlende Funktion bereitstellen, vor allem RecordBuilder:

@RecordBuilder
record Customer(UUID id, String name) {}

var customer = new Customer(UUID.randomUUID(), "John");
var renamed = customer.withName("John Doe");

Erzwingen von Nicht-Null

Eine besondere Art der Validierung besteht darin, zu erzwingen, dass Datensatzfelder nicht null sind. (Un)glücklicherweise haben Datensätze kein besonderes Verhalten in Bezug auf Nullbarkeit.
Sie können Tools wie NullAway oder Error Prone verwenden, um null in Ihrem Code generell zu verhindern, oder Sie können Ihren Datensätzen Prüfungen hinzufügen:

record Customer(UUID id, String name) {
    Customer {
        Objects.requireNonNull(id, "id cannot be null");
        Objects.requireNonNull(name, "name cannot be null");
    }
}

Abgeleitete Daten

Manchmal müssen Sie die primären Daten in einem Datensatz verwenden, um andere Daten abzuleiten. Genau wie bei POJOs können Sie einfach eine Methode hinzufügen:

record Customer(String firstName, String lastName) {
    public String fullName() {
        return String.format("%s %s", firstName, lastName);
    }
}

Genau wie bei POJOs werden diese Werte nicht gepuffert, sondern nachlässig berechnet.
Anders als bei POJOs können Sie dies nicht durch Hinzufügen eines Feldes eifrig und gepuffert machen, da Datensätze keine Felder haben dürfen:

record Customer(String firstName, String lastName) {
    // This will give a compile error, records are not allowed to have fields
    private final String fullName = String.format("%s %s", firstName, lastName)
}

Eine Alternative ist die Verwendung der Gültigkeitsprüfung und das Hinzufügen des Feldes als Datensatzkomponente:

record Customer(String firstName, String lastName, String fullName) {
    public Customer {
      fullName = String.format("%s %s", firstName, lastName);
    }

    public Customer(String firstName, String lastName) {
        this(firstName, lastName, null);
    }
}

var customer = new Customer("John", "Doe");
// This will be "John Doe", and is already computed and cached
var fullName = customer1.fullName();

Seien Sie damit jedoch vorsichtig, da es für die Benutzer des Datensatzes überraschend sein könnte. Im Allgemeinen würde ich empfehlen, stattdessen ein POJO mit einem privaten Endfeld zu verwenden.

var customer = new Customer("John", "Doe", "Austin Powers");
// This will unexpectedly be "John Doe" instead of "Austin Powers"
var fullName = customer.fullName();



Verfasst von

David Hoepelman

Contact

Let’s discuss how we can support your journey.