© Enkel/Shutterstock.com
Ein Blick auf JEP 359: Java Records

Rekordverdächtig strukturiert


Datenklassen, also Java-Klassen, deren einziger Zweck darin besteht, Daten zu halten und diese über Getter und Setter zugänglich zu machen, gehören in vielen Softwareprojekten zu den größten Sammelstellen von Boilerplate-Code. Für jede neue Klasse jeweils Konstruktoren, die Methoden equals, hashCode und toString und für jedes Feld noch einen Getter und einen Setter zu erstellen, ist für viele Entwickler eine verhasste Zeremonie geworden – sofern sie nicht direkt Bibliotheken wie Lombok einsetzen, um dieser zu entgehen. JEP 359 soll Abhilfe schaffen.

Mit JEP 359 werden Records in die JVM eingeführt – wenn auch vorerst nur als Preview Feature. Um sie ausprobieren zu können, müssen sowohl der Compiler als auch das erstellte Programm mit dem Flag --enable-preview ausgeführt werden.

Das Problem, das mit Records gelöst werden soll

Was genau macht das Erstellen von Datenklassen in Java so mühsam? Das Herzstück solcher Klassen ist die definierte Liste von Instanzvariablen, die die Zustandsbeschreibung eines Objekts darstellen. Möchten Entwickler eine Klasse entwerfen, die einen Würfel widerspiegelt, kommen sie mit drei Variablen aus: Höhe, Breite und Tiefe. Um mit Instanzen des Typs Würfel arbeiten zu können, müssen sie allerdings weitere Formalitäten erfüllen: Die Klasse benötigt Konstruktoren, Getter und Setter. Ebenfalls müssen die Methoden equals, hashCode und toString überschrieben werden. Diese gesamte Arbeit läuft in den allermeisten Fällen so gleichförmig ab, dass Entwickler sie automatisiert von ihrer Entwicklungsumgebung vornehmen lassen: Für jede Instanzvariable werden Getter und Setter erstellt, alle sollen bei hashCode, equals und toString berücksichtigt werden (oder schlimmer: hashCode und equals werden erst gar nicht implementiert). Oft wird auch noch ein Konstruktor definiert, der sämtliche Variablen als Parameter enthalten kann, um ein Objekt vollständig initialisiert erstellen zu können. Nach dieser Prozedur hat die Klasse dann knapp 65 Zeilen Code, von denen etwa fünf ausreichen, um die wichtigste Information zu beschreiben – den Namen, den Modifier und welchen Zustand sie hält.

Natürlich können an einem Würfel auch seine Oberfläche, Kantenlänge oder sein Volumen interessant sein – diese Werte leiten sich aber von seiner Zustandsbeschreibung ab und stellen keine neuen Variablen dar. Um das Volumen des Würfels zu erhalten, würden Entwickler eine Methode calculateVolume() bereitstellen, die die Länge, Höhe und Breite des Würfels multipliziert. Auch diese Methoden enthalten Informationen, die für alle Entwickler des Teams wichtig sind, um die Eigenschaften eines Würfels zu verstehen. Sie zwischen den anderen neun Methoden zu identifizieren, die vorhin von der Entwicklungsumgebung generiert wurden, kann auf den ersten Blick unter Umständen schwierig sein. Die Klasse vermischt das „Was“ mit dem „Wie“, sie hat eine unnötig hohe kognitive Komplexität. Mit der Einführung von Records soll exakt dieses Problem vermieden werden, indem Daten auch als Daten modelliert werden und der Zugriff darauf sich aus dem Kontext ergibt.

Aufbau und Struktur von Records

Records sind eine neue Typendeklaration in Java und stellen eine spezialisierte Form einer Klasse dar. Sie sind für einen klar definierten Zweck gedacht, haben gegenüber herkömmlichen Klassen aber Einschränkungen, ähnlich wie Enums. Die Zustandsbeschreibung des Records wird über die Definition von sogenannten Komponenten vorgenommen, die aus einem Typ und einer Bezeichnung bestehen. Ein simpler Record, der einen Würfel mit den Komponenten „Höhe“, „Breite“ und „Tiefe“ beschreibt, findet sich nachfolgend:

public record Wuerfel(int hoehe, int breite, int tiefe) {}

Eine vergleichbar aufgebaute herkömmliche Klasse zeigt Listing 1.

Listing 1

public final class Wuerfel { private final int height; private final int width; private final int depth; public Wuerfel(int height, int width, int depth) { this.height = height; this.width = width; this.depth = depth; } public int getHeight() { return height; } public int getWidth() { return width; } public int getDepth() { return depth; } @Override p...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang