DEV Community

PythonIsNotASnake
PythonIsNotASnake

Posted on • Edited on

Java records und wieso du sie nutzen solltest [German]

Falls du ein Einsteiger bist, welcher aktuell Java lernt, kennst du bereits die Basiselemente wie Klassen, Methoden, Enums und so weiter. Jedoch gibt es seit Java 16 fest im Java Funktionsumfang verankert records. Dieses kurze Tutorial wird dir erklären, was records in Java sind, sowie einige Tipps dazugeben, wie du sie in deinem nächsten Projekt verwenden kannst.
Alle Informationen in diesem Tutorial basieren auf der Java 16 records Dokumentation, sowie meinen eigenen Erfahrungen.

Was sind record?

Einfach erklärt sind records eine Abstrahierung von Java Beans. Ein record definiert automatisch einen All arguments Konstruktor und gibt public Zugriff zu allen properties des records. Ein record hat von sich aus keine weiteren Methoden. Es ist schlicht ein dummes Java Objekt ohne weitere Funktionalität.

Wie wird ein record implementiert?

Ähnlich zu Enums kann ein record Bestandteil einer Java Klasse sein oder eine eigenständige Datei darstellen.
Als Beispiel möchten wir einen Bruch (engl. fraction) definieren. Ein Bruch besteht aus einem Zähler (engl. numerator) und einem Nenner (engl. denominator). Möchten wir dieses Objekt nun als Java Klasse schreiben sieht es wie folgt aus:

public class Fraction {
  private double numerator;
  private double denominator;

  public Fraction() {
    this.numerator = 0.0;
    this.denominator = 1.0;
  }

  public Fraction(double numerator, double denominator) {
    this.numerator = numerator;
    this.denominator = denominator;
  }

  public void setNumerator(double numerator) {
    this.numerator = numerator;
  }

  public double getNumerator() {
    return this.numerator;
  }

  public void setDenominator(double denominator) {
    this.denominator= denominator;
  }

  public double getDenominator() {
    return this.denominator;
  }
}
Enter fullscreen mode Exit fullscreen mode

Wie du erkennen kannst ist dies ziemlich viel Code um lediglich eine Klasse mit zwei Attributen zu beschreiben. Und nun lass uns dasselbe als record geschrieben betrachten:

public record Fraction(double numerator, double denominator) {}
Enter fullscreen mode Exit fullscreen mode

Kurz, oder? Und das ist der wichtigste Grund für die Verwendung von records. Diese einzelne Zeile bündelt einen All Arguments Konstruktor und die beiden public Attribute numerator und denominator.
Möchtest du eine neue Instanz dieses records erzeugen, so tust du dies wie für gewöhnliche Klassen auch.

Fraction fractionAsRecord = new Fraction(0.0, 1.0);
Enter fullscreen mode Exit fullscreen mode

Override von Konstruktoren und Getter/Setter

Falls der vordefinierte Konstruktor und die Getter/Setter Methoden deinen Use Case nicht sinnvoll abdecken, kannst du diese auch überschreiben. Für einen Konstruktor würdest du es wie folgt machen:

public record Fraction(double numerator, double denominator) {
  public Fraction(double numerator, double denominator) {
    if (numerator == 0 && denominator == 0) {
      throw new java.lang.IllegalArgumentException(
        "Invalid fraction: " + numerator + "/" + denominator
      );
    }
    this.numerator = numerator;
    this.denominator = denominator;
  }
}
Enter fullscreen mode Exit fullscreen mode

Wie du siehst, wird hier nicht wie üblich die Override Annotation benötigt. Dasselbe kann ebenfalls für die Methoden double numerator() oder void numerator(double numerator) getan werden.

Statische Attribute und Methoden

Nun kommen wir zu einer erweiterten Funktion von records. Records geben dir die Möglichkeit statische Attribute und statische Methoden zu definieren. Für unser Beispiel möchten wir unseren Bruch durch den Wert zwei dividieren. Dafür können wir ein statisches Attribut static double half = 2.0 und eine statische Methode static Fraction divideByTwo(Fraction fr) implementieren.

public record Fraction(double numerator, double denominator) {
  static double half = 2;

  public static Fraction divideByTwo(Fraction fr) {
    return new Fraction(fr.numerator(), fr.denominator() * half);
  }
}
Enter fullscreen mode Exit fullscreen mode

Die oben aufgeführte Methode kann mittels Fraction.divideByTwo(fraction) aufgerufen werden. Wie du sehen kannst, kannst du Records um deine benötigten Methoden erweitern, vorausgesetzt diese sind statisch. Dies gibt dir etwas mehr Flexibilität beim Einsatz von Records.

Andere nützliche Funktionen

In der java 16 Dokumentation sind eine Anzahl weiterer erweiterter Funktionalitäten, welche ich hiermit kurz erwähne aber nicht detailliert auf alle eingehe. Du kannst diese im eben erwähnten Link im Abschnitt "Features of Record Classes" finden.
Für mich persönlich ist die Option, dass Records Interfaces implementieren können am nützlichsten. Beispielsweise kannst du einige Basis Methoden für eine Gruppe von Records definieren. Ich gebe dir ein kurzes Beispiel mit dem Interface Mathobject:

public interface Mathobject {
  public Mathobject divideByTwo();
}
Enter fullscreen mode Exit fullscreen mode

Wenn wir unseren Fraction Record dieses Interface implementieren lassen, können wir unsere statische Methode divideByTwo umschreiben. Dies sieht dann wie folgt aus:

public record Fraction(double numerator, double denominator) implements Mathobject {
  static double half = 2;

  @Override
  public Fraction multiplyByTwo() {
    return new Fraction(numerator, denominator * half);
  }
}
Enter fullscreen mode Exit fullscreen mode

Der Record überschreibt die Methode des Interface Mathobject und lässt uns die beiden Attribute von Fraction innerhalb der Methode nutzen, da diese nicht mehr statisch ist.

Abschluss

Was macht Records am Ende so nützlich?
Sie produzieren signifikant weniger Boilerplate Code.
Zudem kennt jeder erfahrene Java Entwickler das Prinzip von Records und kann somit diesen übersichtlichen Code sehr leicht verstehen. Somit wird dein Code verständlicher und orderntlicher.
Und das allerwichtigste ist der Aspekt, dass du weniger Code schreiben musst, was zu einer Zeitersparnis führt.

Keep coding.

Here you can find the english version.

Top comments (0)