Rekordy (Java 16+)
Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 51 z 87.
Podczas tworzenia prostych klas przechowujących dane często piszesz powtarzalny kod szablonowy: pola prywatne, konstruktor, metody pobierające, toString(), equals() i hashCode(). W Java 16 wprowadzono rekordy, aby wyeliminować tę żmudną pracę.
Rekord to specjalna klasa przeznaczona do przechowywania niezmiennych danych. Deklarujesz go za pomocą słowa kluczowego record, po którym następuje lista komponentów:
record Person(String name, int age) { }
// Ta jedna linia automatycznie zapewnia:
// - pola private final: name i age
// - konstruktor: Person(String name, int age)
// - metody dostępowe: name() i age()
// - toString(), equals() i hashCode()Korzystanie z rekordu jest proste:
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]Zwróć uwagę, że metody dostępowe nie używają przedrostka get: ich nazwy są po prostu takie same jak nazwy pól. Rekordy są niejawnie final, więc nie można ich rozszerzać. Wszystkie pola również są final, dzięki czemu rekordy są z natury niezmienne.
W razie potrzeby możesz dodawać własne metody i nadpisywać te generowane automatycznie. Możesz również dodać walidację w konstruktorze kompaktowym:
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Rekordy idealnie sprawdzają się w przypadku obiektów DTO, odpowiedzi API lub w każdej sytuacji, gdy potrzebujesz prostego, niemodyfikowalnego kontenera danych bez pisania powtarzalnego kodu.
Wyzwanie
ŁatwyZbudujmy system rezerwacji biletów na filmy, który pokazuje elegancję rekordów w Java. Zobaczysz, jak rekordy eliminują powtarzalny kod, a jednocześnie pozwalają dodawać własne metody i walidację.
Rozmieścisz swój kod w trzech plikach:
Movie.java: Utwórz rekord reprezentujący film z trzema komponentami:title(String),genre(String) idurationMinutes(int). Dodaj własną metodę o nazwiegetFormattedDuration(), która zwraca czas trwania w czytelnym formacie:[hours]h [minutes]m(na przykład 142 minuty to2h 22m). Użyj dzielenia całkowitego i operatora modulo, aby obliczyć liczbę godzin i pozostałych minut.Ticket.java: Utwórz rekord reprezentujący bilet na film z trzema komponentami:movie(Movie),seatNumber(String) iprice(double). Dodaj konstruktor kompaktowy, który sprawdza cenę: jeśli cena jest mniejsza lub równa zero, rzuć wyjątekIllegalArgumentExceptionz komunikatemPrice must be positive. Dodaj także własną metodę o nazwieprintTicket(), która zwraca wielowierszowy ciąg znaków:========== TICKET ========== Movie: [movie title] Genre: [movie genre] Duration: [formatted duration from movie] Seat: [seatNumber] Price: $[price] ============================Main.java: Połącz elementy swojego systemu rezerwacji! Otrzymasz pięć danych wejściowych: tytuł filmu (String), gatunek (String), czas trwania w minutach (int), numer miejsca (String) i cenę biletu (double).Utwórz rekord Movie z pierwszych trzech danych wejściowych, a następnie utwórz rekord Ticket z filmem, numerem miejsca i ceną. Wypisz wynik wywołania metody
printTicket()na swoim bilecie.
Otrzymasz kolejno pięć danych wejściowych: tytuł filmu, gatunek, czas trwania (w minutach), numer miejsca i cenę.
Zwróć uwagę, o ile czytelniejsze są rekordy w porównaniu z tradycyjnymi klasami: nie trzeba pisać konstruktorów, getterów, toString(), equals() ani hashCode(). Konstruktor kompaktowy pozwala dodać walidację bez powtarzania przypisań pól, a w razie potrzeby nadal możesz dodawać własne metody!
Spróbuj swoich sił
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Wczytaj dane wejściowe
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: Utwórz rekord Movie z polami title, genre i durationMinutes
// TODO: Utwórz rekord Ticket z filmem, seatNumber i price
// TODO: Wypisz bilet za pomocą metody printTicket()
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe thisMetodyPola (atrybuty)Metoda konstruktoraPrzeciążanie konstruktoraPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawy dziedziczenia (extends)Słowo kluczowe superPrzesłanianie metod (@Override)Łańcuch wywołań konstruktorówKlasa ObjectDziedziczenie jedno- i wielopoziomoweDlaczego Java nie obsługuje wielodziedziczenia klasPodsumowanie – hierarchia pracowników7Metody specjalne i klasa Object
Metoda toString()equals() i hashCode()Metoda clone()compareTo() i ComparableInterfejs ComparatorPodsumowanie — własne sortowanie10Obsługa wyjątków w programowaniu obiektowym
Hierarchia klas wyjątkówWłasne wyjątkiBłędy sprawdzane a niesprawdzaneWzorzec try-with-resourcesPodsumowanie – zweryfikowany użytkownik2Modyfikatory dostępu i enkapsulacja
Przegląd poziomów dostępuMetody pobierające i ustawiająceUkrywanie informacjiSłowo kluczowe finalPodsumowanie — menedżer kont bankowych5Polimorfizm
Podstawy przeciążania metodPrzesłanianie metod (w czasie wykonywania)Rzutowanie w górę i w dółOperator instanceofKlasy i metody abstrakcyjnePowtórka — kalkulator figur8Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieAgregacja a kompozycjaKlasy wewnętrzne, zagnieżdżone i anonimoweEnumy i metody enumówRekordy (Java 16+)Klasy zapieczętowane (Java 17+)11Wzorce projektowe — część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec BuilderWzorzec ObserverWzorzec Strategy3Właściwości klas i składowe statyczne
Zmienne instancji a zmienne statyczneMetody statyczneBloki statyczneStałe (static final)Powtórka – Counter i Utility6Interfejsy i klasy abstrakcyjne
Wprowadzenie do interfejsówImplementowanie interfejsówImplementacja wielu interfejsówMetody domyślne i statyczne w interfejsieKlasy abstrakcyjne a interfejsyInterfejsy funkcyjnePodsumowanie — system płatnościPoćwicz samodzielnie: Kompilator Java online