Records (Java 16+)
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 51 sur 87.
Lors de la création de classes simples de transport de données, vous écrivez souvent du code répétitif (boilerplate) : des champs privés, un constructeur, des getters, toString(), equals() et hashCode(). Java 16 a introduit les records pour éliminer cette tâche fastidieuse.
Un record est une classe spéciale conçue pour contenir des données immuables. Vous le déclarez avec le mot-clé record suivi de la liste des composants :
record Person(String name, int age) { }
// Cette seule ligne fournit automatiquement :
// - des champs private final : name et age
// - un constructeur : Person(String name, int age)
// - des méthodes d'accès : name() et age()
// - toString(), equals(), et hashCode()L'utilisation d'un record est simple :
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]Remarquez que les méthodes d'accès n'utilisent pas le préfixe get — elles portent simplement le nom des champs. Les records sont implicitement final, ils ne peuvent donc pas être étendus. Tous les champs sont également final, ce qui rend les records intrinsèquement immuables.
Vous pouvez ajouter des méthodes personnalisées et surcharger celles générées automatiquement si nécessaire. Vous pouvez également ajouter une validation dans un constructeur compact :
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Les records sont parfaits pour les DTO, les réponses d'API ou tout scénario où vous avez besoin d'un conteneur de données simple et immuable sans écrire de code répétitif.
Défi
FacileConstruisons un système de réservation de billets de cinéma qui met en valeur l'élégance des records Java. Vous verrez comment les records éliminent le code répétitif (boilerplate) tout en vous permettant d'ajouter des méthodes personnalisées et de la validation.
Vous organiserez votre code sur trois fichiers :
Movie.java: Créez un record représentant un film avec trois composants :title(String),genre(String), etdurationMinutes(int). Ajoutez une méthode personnalisée appeléegetFormattedDuration()qui renvoie la durée dans un format convivial :[hours]h [minutes]m(par exemple, 142 minutes deviennent2h 22m). Utilisez la division entière et le modulo pour calculer les heures et les minutes restantes.Ticket.java: Créez un record représentant un billet de cinéma avec trois composants :movie(Movie),seatNumber(String), etprice(double). Ajoutez un constructeur compact qui valide le prix — si le prix est inférieur ou égal à zéro, lancez uneIllegalArgumentExceptionavec le message"Price must be positive". Ajoutez également une méthode personnalisée appeléeprintTicket()qui renvoie une chaîne multi-lignes :========== TICKET ========== Movie: [movie title] Genre: [movie genre] Duration: [formatted duration from movie] Seat: [seatNumber] Price: $[price] ============================Main.java: Rassemblez votre système de réservation ! Vous recevrez cinq entrées : le titre du film (String), le genre (String), la durée en minutes (int), le numéro de siège (String) et le prix du billet (double).Créez un record Movie avec les trois premières entrées, puis créez un record Ticket avec le film, le numéro de siège et le prix. Affichez le résultat de l'appel à
printTicket()sur votre billet.
Vous recevrez cinq entrées dans l'ordre : le titre du film, le genre, la durée (minutes), le numéro de siège et le prix.
Remarquez à quel point les records sont plus propres par rapport aux classes traditionnelles — pas besoin d'écrire de constructeurs, de getters, de toString(), d'equals() ou de hashCode(). Le constructeur compact vous permet d'ajouter de la validation sans répéter les affectations de champs, et vous pouvez toujours ajouter des méthodes personnalisées si nécessaire !
Aide-mémoire
Java 16 a introduit les records pour éliminer le code répétitif (boilerplate) pour les classes simples de transport de données. Un record est une classe spéciale conçue pour contenir des données immuables.
Déclarez un record avec le mot-clé record suivi de la liste des composants :
record Person(String name, int age) { }Cela fournit automatiquement :
- Des champs privés finaux (private final)
- Un constructeur
- Des méthodes d'accès (sans le préfixe
get) toString(),equals(), ethashCode()
Utilisation d'un record :
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]Les records sont implicitement final et ne peuvent pas être étendus. Tous les champs sont final, ce qui rend les records intrinsèquement immuables.
Ajoutez une validation en utilisant un constructeur compact :
record Person(String name, int age) {
public Person {
if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
}
}Vous pouvez ajouter des méthodes personnalisées aux records :
record Person(String name, int age) {
public String getInfo() {
return name + " is " + age + " years old";
}
}Essayez vous-même
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lire les entrées
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: Créer un record Movie avec title, genre, et durationMinutes
// TODO: Créer un record Ticket avec movie, seatNumber, et price
// TODO: Afficher le ticket en utilisant la méthode printTicket()
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron Itérateur