Geschichte der Frage:
Record-Klassen (record) wurden in Java 14 als Vorschau eingeführt, seit dem Release von Java 16 ist dies eine stabile Funktion. Sie implementieren das Konzept von unveränderlichen (immutable) Containern zur Speicherung von Daten, die Werten-Objekten ähnlich sind. Dies ist eine Reaktion auf die Wortfülle klassischer DTOs und POJOs in Java.
Problem:
Für einfache datentragende Objekte musste man manuell Konstruktoren, equals(), hashCode(), toString() implementieren. Dies ist Arbeit, die fehleranfällig ist und viele Codezeilen erfordert.
Lösung:
Eine Record-Klasse wird in einer Zeile deklariert und erhält automatisch einen Konstruktor, Getter, equals(), hashCode(), toString(). Die Felder eines Record sind unveränderlich (final), Records sind besonders nützlich, um Informationen zwischen den Schichten der Anwendung zu übertragen.
Beispielcode:
public record Point(int x, int y) {} Point p = new Point(3, 5); System.out.println(p.x()); // 3 System.out.println(p); // Point[x=3, y=5]
Wesentliche Merkmale:
Kann der Zustand eines Record-Objekts nach seiner Erstellung geändert werden?
Nein – alle Felder sind final, man kann den Wert auf keine Weise ändern.
Kann man Record mit nicht-standardmäßiger Logik im Konstruktor erstellen?
Ja, man kann einen kompakten oder regulären Konstruktor definieren und Überprüfungen hinzufügen:
public record Point(int x, int y) { public Point { if (x < 0 || y < 0) throw new IllegalArgumentException(); } }
Kann ein Record abstrakt sein oder Felder/Logik anderer Klassen erben?
Nein – ein Record ist immer final. Er kann Interfaces implementieren, aber nicht Klassen erben, außer Object.
Verwendung langer POJOs für jede Anfrage/Antwort, mit manueller Implementierung von equals, hashCode, toString, Konstruktoren und Gettern.
Vorteile:
Nachteile:
Übertragung aller DTOs in Record-Klassen:
public record UserDTO(String login, String email) {}
Vorteile:
Nachteile: