Records (Java 16+)
Teil des Abschnitts Objektorientierte Programmierung der Java-Journey von Coddy — Lektion 51 von 87.
Beim Erstellen einfacher datenführender Klassen schreiben Sie oft repetitiven Boilerplate-Code: private Felder, einen Konstruktor, Getter, toString(), equals() und hashCode(). Java 16 führte Records ein, um diese mühsame Arbeit zu eliminieren.
Ein Record ist eine spezielle Klasse, die dazu dient, unveränderliche Daten zu speichern. Sie deklarieren ihn mit dem Schlüsselwort record, gefolgt von der Komponentenliste:
record Person(String name, int age) { }
// Diese einzige Zeile bietet automatisch:
// - 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]Beachten Sie, dass Accessor-Methoden 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, was Records von Natur aus unveränderlich macht.
Sie können benutzerdefinierte Methoden hinzufügen und die automatisch generierten bei Bedarf überschreiben. Sie können auch Validierungen 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 sind perfekt für DTOs, API-Antworten oder jedes Szenario, in dem Sie einen einfachen, unveränderlichen Datencontainer benötigen, ohne Boilerplate-Code schreiben zu müssen.
Aufgabe
EinfachLassen Sie uns ein Kinoticket-Buchungssystem erstellen, das die Eleganz von Java-Records demonstriert. Sie werden sehen, wie Records Boilerplate-Code eliminieren und es Ihnen dennoch ermöglichen, benutzerdefinierte Methoden und Validierungen hinzuzufügen.
Sie werden Ihren Code über drei Dateien organisieren:
Movie.java: Erstellen Sie einen Record, der einen Film mit drei Komponenten darstellt:title(String),genre(String) unddurationMinutes(int). Fügen Sie eine benutzerdefinierte Methode namensgetFormattedDuration()hinzu, die die Dauer in einem freundlichen Format zurückgibt:[hours]h [minutes]m(zum Beispiel werden 142 Minuten zu2h 22m). Verwenden Sie Ganzzahldivision und Modulo, um Stunden und verbleibende Minuten zu berechnen.Ticket.java: Erstellen Sie einen Record, der ein Kinoticket mit drei Komponenten darstellt:movie(Movie),seatNumber(String) undprice(double). Fügen Sie einen kompakten Konstruktor hinzu, der den Preis validiert – wenn der Preis kleiner oder gleich Null ist, werfen Sie eineIllegalArgumentExceptionmit der NachrichtPrice must be positive. Fügen Sie außerdem eine benutzerdefinierte 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: Bringen Sie Ihr Buchungssystem zusammen! Sie erhalten fünf Eingaben: Filmtitel (String), Genre (String), Dauer in Minuten (int), Sitzplatznummer (String) und Ticketpreis (double).Erstellen Sie einen Movie-Record mit den ersten drei Eingaben und erstellen Sie dann einen Ticket-Record mit dem Film, der Sitzplatznummer und dem Preis. Geben Sie das Ergebnis des Aufrufs von
printTicket()auf Ihrem Ticket aus.
Sie erhalten fünf Eingaben in der Reihenfolge: Filmtitel, Genre, Dauer (Minuten), Sitzplatznummer und Preis.
Beachten Sie, wie viel sauberer Records im Vergleich zu herkömmlichen Klassen sind – es ist nicht nötig, Konstruktoren, Getter, toString(), equals() oder hashCode() zu schreiben. Der kompakte Konstruktor ermöglicht es Ihnen, Validierungen hinzuzufügen, ohne Feldzuweisungen zu wiederholen, und Sie können bei Bedarf weiterhin benutzerdefinierte Methoden hinzufügen!
Spickzettel
Java 16 hat Records eingeführt, um Boilerplate-Code für einfache datenführende Klassen zu eliminieren. Ein Record ist eine spezielle Klasse, die darauf ausgelegt ist, unveränderliche Daten zu halten.
Deklarieren Sie einen Record mit dem Schlüsselwort record, gefolgt von der Komponentenliste:
record Person(String name, int age) { }Dies stellt automatisch Folgendes bereit:
- Private finale Felder
- Einen Konstruktor
- Accessor-Methoden (ohne
get-Präfix) toString(),equals()undhashCode()
Verwendung eines Records:
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]Records sind implizit final und können nicht erweitert werden. Alle Felder sind final, wodurch Records von Natur aus unveränderlich sind.
Fügen Sie eine Validierung mit einem kompakten Konstruktor hinzu:
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Sie können Records benutzerdefinierte Methoden hinzufügen:
record Person(String name, int age) {
public String getInfo() {
return name + " is " + age + " years old";
}
}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 ein Movie record mit title, genre und durationMinutes
// TODO: Erstelle ein Ticket record mit movie, seatNumber und price
// TODO: Drucke das Ticket mit der Methode printTicket()
}
}
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 this-SchlüsselwortMethodenFelder (Attribute)Konstruktor-MethodeKonstruktor-ÜberladungRückblick – Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (extends)Das super-SchlüsselwortMethoden überschreiben (@Override)Konstruktor-VerkettungDie Object-KlasseEinfache & mehrstufige VererbungWarum keine Mehrfachvererbung von KlassenZusammenfassung - Mitarbeiter-Hierarchie7Spezielle Methoden & Object-Klasse
toString()-Methodeequals() und hashCode()clone()-MethodecompareTo() und ComparableComparator-InterfaceZusammenfassung – Benutzerdefiniertes Sortieren2Zugriffsmodifikatoren & Kapselung
Überblick über ZugriffsebenenGetter- und Setter-MethodenInformation HidingDas final-SchlüsselwortRückblick – Bankkonto-Manager5Polymorphismus
Grundlagen der MethodenüberladungMethodenüberschreibung (Laufzeit)Upcasting und DowncastingDer instanceof-OperatorAbstrakte Klassen und MethodenZusammenfassung – Formenrechner8Fortgeschrittene OOP-Konzepte
Komposition vs. VererbungAggregation vs. KompositionInnere, geschachtelte & anonyme KlassenEnums und Enum-MethodenRecords (Java 16+)Sealed Classes (Java 17+)11Design Patterns Teil 1
Einführung in Design PatternsSingleton-PatternFactory-PatternBuilder-PatternObserver-PatternStrategy-Pattern14Abschlussherausforderungen
E-Learning-PlattformBanksystemSpielcharakter-EntwicklungFahrzeugvermietung3Klasseneigenschaften & Statische Member
Instanz- vs. statische VariablenStatische MethodenStatische BlöckeKonstanten (static final)Zusammenfassung – Zähler & Utility6Interfaces & Abstrakte Klassen
Einführung in InterfacesInterfaces implementierenImplementierung mehrerer InterfacesDefault- & statische Methoden in InterfacesAbstrakte Klassen vs. InterfacesFunktionale InterfacesZusammenfassung - Zahlungssystem