Home > Informatik > Einführung in die OOP > 11. Records > Was sind Records ?

11.1 Was sind Records?

Records in der Sprache Pascal

In der etwas älteren Programmiersprache Pascal gibt es den Datentyp Record. Hier ein einfaches Beispiel:

type
   Person = record
      Name    : string;
      Vorname : string;
      Alter   : integer;
   end;

Bei einem Pascal-Record handelt es sich um eine Datenstruktur, die mehrere Datenfelder unterschiedlicher oder gleicher Datentypen zusammenfasst. Im obigen Beispiel fasst der Record Person die drei Felder Name, Vorname und Alter zusammen. Die ersten beiden Felder haben den Typ string, das dritte den Typ integer.

Wie kann man in Pascal auf einen solchen Record zugreifen? Das sehen wir uns an einem weiteren Beispiel an:

var p : Person;

begin
   p.Name := 'Meier';
   p.Vorname := 'Anna';
   p.Alter := 23;
end.

Records in der Sprache Java

In der Sprache Java wurden Records stufenweise eingeführt. In Java 14 (März 2020) wurden Records erstmals vorgestellt, allerdings nur als Preview-Feature. Im März 2021 wurden mit Java 16 Records offizieller Bestandteil der Sprache Java.

Erstellung eines Records

Ein Java-Record, der dem obigen Pascal-Record entspricht, sieht so aus:

public record Person(String name, String vorname, int alter)
{
}

oder noch kürzer:

public record Person(String name, String vorname, int alter){}

Die drei Komponenten name, vorname und alter werden direkt im Kopf des Records angegeben. Der Compiler erzeugt daraus automatisch drei private und finale Instanzvariablen. Außerdem wird automatisch ein Konstruktor erzeugt, der die übergebenen Werte den Instanzvariablen zuweist. Dieser Konstruktor wird als kanonischer Konstruktor bezeichnet.

Da die Instanzvariablen eines Records final sind, können sie nach der Erzeugung des Objekts nicht mehr verändert werden. Daher besitzen Records normalerweise keine Setter-Methoden.

Für jede Komponente erzeugt der Compiler außerdem automatisch eine Zugriffsmethode. Im Gegensatz zu den üblichen Getter-Methoden beginnen diese Methoden nicht mit dem Präfix get, sondern tragen exakt den Namen der jeweiligen Komponente.

Zugriff auf einen Record

Der folgende Code demonstriert, wie man auf die Daten eines solchen Records zugreifen kann:

Person p = new Person("Jens", "Müller", 23);

System.out.println(
   p.vorname() + " " + p.name() + " ist " +
   p.alter() + " Jahre alt.");

Ein Objekt des Records Person wird genauso deklariert und initialisiert wie ein Objekt einer normalen Klasse.

Eine normale Klasse Person müsste die drei Instanzvariablen, einen passenden Konstruktor sowie mehrere Zugriffsmethoden ausdrücklich im Quelltext enthalten. Häufig kämen außerdem Setter-Methoden hinzu, wenn die gespeicherten Werte nachträglich verändert werden sollen.

Ein Record besitzt normalerweise keine Setter-Methoden. Setter-Methoden sowieso keinen Sinn ergeben, denn die Komponenten des Records sind final, also nicht mehr veränderbar, nachdem sie einmal gesetzt wurden.

Getter-Methoden mit dem Präfix get müssen bei einem Record ebenfalls nicht implementiert werden. Stattdessen verwendet man die automatisch erzeugten Zugriffsmethoden, deren Namen den Komponenten entsprechen, also zum Beispiel name(), vorname() und alter().

Zusätzlich zu diesen Zugriffsmethoden erzeugt der Compiler automatisch passende Implementierungen der folgenden Methoden:

  • eine toString()-Methode
  • eine equals()-Methode
  • eine hashCode()-Methode

Auch normale Java-Klassen besitzen diese Methoden, da sie von der Oberklasse Object geerbt werden. Allerdings müssen normale Java-Klassen diese Methoden überschreiben, wenn sie sinnvoll mit den gespeicherten Daten arbeiten sollen. Bei einem Record werden die drei Methoden dagegen automatisch passend zu den Komponenten implementiert. Bei Bedarf können diese Methoden aber überschrieben werden.

Sinn und Zweck von Records

Records wurden vor allem eingeführt, um sogenannte Datenklassen kompakter zu formulieren. Eine Datenklasse ist eine Klasse, deren Hauptaufgabe darin besteht, zusammengehörende Daten zu einem Objekt zusammenzufassen (ähnlich wie die Records in Pascal).

Ohne Records müsste man für solche einfachen Datenobjekte relativ viel Quelltext schreiben: Instanzvariablen, Konstruktor, Getter-Methoden und bei Bedarf auch eigene Versionen von toString(), equals() und hashCode().

Bei einem Record wird dieser ganze Code automatisch vom Compiler erzeugt.

Records eignen sich besonders gut für Objekte, deren Werte nach der Erzeugung nicht mehr verändert werden sollen. Man spricht hier auch von unveränderlichen oder immutable Objekten.

Records sind jedoch kein vollständiger Ersatz für normale Klassen. Wenn ein Objekt umfangreiche Zustandsänderungen durchführen soll, viele Setter-Methoden benötigt oder ein komplexes Verhalten besitzt, sollte man besser eine normale Klasse einsetzen.