Records (Java 16+)
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy. Lektion 51 von 87.
Beim Erstellen einfacher Klassen zur Datenspeicherung schreibst du oft sich wiederholenden Boilerplate-Code: private Felder, einen Konstruktor, Getter, toString(), equals() und hashCode(). Java 16 führte Records ein, um diese Mühsal zu beseitigen.
Ein Record ist eine spezielle Klasse, die dafür entwickelt wurde, unveränderliche Daten zu speichern. Du deklarierst ihn mit dem Schlüsselwort record, gefolgt von der Komponentenliste:
record Person(String name, int age) { }
// Diese einzelne Zeile stellt automatisch bereit:
// - private final Felder: name und age
// - einen Konstruktor: Person(String name, int age)
// - Zugriffsmethoden: name() und age()
// - toString(), equals() und hashCode()Die Verwendung eines Records ist unkompliziert:
Person p = new Person("Alice", 30);
System.out.println(p.name()); // Alice
System.out.println(p.age()); // 30
System.out.println(p); // Person[name=Alice, age=30]Beachte, dass Zugriffsmethoden nicht das Präfix get verwenden: Sie sind einfach nach den Feldern benannt. Records sind implizit final, daher können sie nicht erweitert werden. Alle Felder sind ebenfalls final, wodurch Records von Natur aus unveränderlich sind.
Du kannst benutzerdefinierte Methoden hinzufügen und die automatisch generierten bei Bedarf überschreiben. Du kannst auch eine Validierung in einem kompakten Konstruktor hinzufügen:
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Records eignen sich perfekt für DTOs, API-Antworten oder jedes Szenario, in dem du einen einfachen, unveränderlichen Datencontainer benötigst, ohne Boilerplate-Code schreiben zu müssen.
Aufgabe
EinfachLass uns ein Kinokarten-Buchungssystem erstellen, das die Eleganz von Java-Records demonstriert. Du wirst sehen, wie Records Boilerplate-Code vermeiden und dir trotzdem ermöglichen, eigene Methoden und Validierungen hinzuzufügen.
Du organisierst deinen Code über drei Dateien:
Movie.java: Erstelle einen Record, der einen Film mit drei Komponenten darstellt:title(String),genre(String) unddurationMinutes(int). Füge eine eigene Methode namensgetFormattedDuration()hinzu, die die Dauer in einem gut lesbaren Format zurückgibt:[hours]h [minutes]m(zum Beispiel werden 142 Minuten zu2h 22m). Verwende Ganzzahldivision und den Modulo-Operator, um die Stunden und die verbleibenden Minuten zu berechnen.Ticket.java: Erstelle einen Record, der eine Kinokarte mit drei Komponenten darstellt:movie(Movie),seatNumber(String) undprice(double). Füge einen kompakten Konstruktor hinzu, der den Preis validiert. Wenn der Preis kleiner oder gleich null ist, löst du eineIllegalArgumentExceptionmit der NachrichtPrice must be positiveaus. Füge außerdem eine eigene Methode namensprintTicket()hinzu, die einen mehrzeiligen String zurückgibt:========== TICKET ========== Movie: [movie title] Genre: [movie genre] Duration: [formatted duration from movie] Seat: [seatNumber] Price: $[price] ============================Main.java: Führe dein Buchungssystem zusammen! Du erhältst fünf Eingaben: Filmtitel (String), Genre (String), Dauer in Minuten (int), Sitzplatznummer (String) und Kartenpreis (double).Erstelle mit den ersten drei Eingaben einen Movie-Record und erstelle anschließend mit dem Film, der Sitzplatznummer und dem Preis einen Ticket-Record. Gib das Ergebnis des Aufrufs von
printTicket()für deine Karte aus.
Du erhältst fünf Eingaben in dieser Reihenfolge: Filmtitel, Genre, Dauer (Minuten), Sitzplatznummer und Preis.
Beachte, wie viel übersichtlicher Records im Vergleich zu herkömmlichen Klassen sind: Du musst keine Konstruktoren, Getter, toString(), equals() oder hashCode() schreiben. Der kompakte Konstruktor ermöglicht es dir, Validierung hinzuzufügen, ohne Feldzuweisungen zu wiederholen, und du kannst bei Bedarf weiterhin eigene Methoden hinzufügen!
Probier es selbst
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Eingaben lesen
String title = scanner.nextLine();
String genre = scanner.nextLine();
int durationMinutes = Integer.parseInt(scanner.nextLine());
String seatNumber = scanner.nextLine();
double price = Double.parseDouble(scanner.nextLine());
// TODO: Erstelle einen Movie-Record mit title, genre und durationMinutes
// TODO: Erstelle einen Ticket-Record mit dem movie, seatNumber und price
// TODO: Gib das Ticket mit der printTicket()-Methode aus
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienEinführung in die OOPKlassen vs. ObjekteDas Schlüsselwort thisMethodenFelder (Attribute)KonstruktormethodeÜberladen von KonstruktorenRückblick – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbung (extends)Das Schlüsselwort superÜberschreiben von Methoden (@Override)KonstruktorverkettungDie Object-KlasseEinfach- und mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenRückblick – Mitarbeiterhierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-SchnittstelleRückblick – Benutzerdefinierte Sortierung2Zugriffsmodifikatoren & Kapselung
Übersicht der ZugriffsebenenGetter- und Setter-MethodenInformationsverbergungDas Schlüsselwort finalRückblick – Bankkontoverwaltung5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenRückblick – Formrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, verschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Versiegelte Klassen (Java 17+)11Entwurfsmuster Teil 1
Einführung in EntwurfsmusterSingleton-MusterFactory-MusterBuilder-MusterObserver-MusterStrategie-Muster14Abschließende Herausforderungen
E-Learning-PlattformBankingsystemEntwicklung einer SpielfigurFahrzeugvermietungsdienst3Klassen-Props & statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Wiederholung – Counter & Utility6Schnittstellen & abstrakte Klassen
Einführung in InterfacesInterfaces implementierenMehrere Interfaces implementierenDefault & Static in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesRückblick – ZahlungssystemÜbe selbstständig: Online-Java-Compiler