0Pricing
Java Academy · Leçon

Découvrir les records

Déclarez des records comme conteneurs de données immuables et concis, puis comprenez leurs membres générés automatiquement.

Découvrir les records est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.

Présentation des enregistrements

Les enregistrements Java (Java 16+) permettent de déclarer de façon concise des classes porteuses de données immuables. Ils génèrent automatiquement le code répétitif : constructeur, accesseurs, equals, hashCode et toString.

Déclarer un enregistrement

Utilisez le mot-clé record, suivi du nom de l’enregistrement et d’une liste de composants. Chaque composant devient un champ privé en lecture seule et une méthode d’accès publique.

record Point(double x, double y) {}

Point p = new Point(3.0, 4.0);
System.out.println(p.x());      // 3.0 (accessor, not getX())
System.out.println(p.y());      // 4.0
System.out.println(p);          // Point[x=3.0, y=4.0]
System.out.println(p.equals(new Point(3.0, 4.0))); // true

Membres générés automatiquement

Pour chaque enregistrement, le compilateur génère automatiquement : le constructeur canonique, les accesseurs publics, equals(), hashCode() et toString(). Il est inutile de les écrire manuellement.

record Product(String name, double price, int stock) {}

Product p1 = new Product("Widget", 9.99, 100);
Product p2 = new Product("Widget", 9.99, 100);

System.out.println(p1.name());          // Widget
System.out.println(p1.price());         // 9.99
System.out.println(p1.equals(p2));      // true (structural)
System.out.println(p1.hashCode() == p2.hashCode()); // true
System.out.println(p1);                 // Product[name=Widget, price=9.99, stock=100]

Les enregistrements sont immuables

Les composants d’un enregistrement sont final. Vous ne pouvez pas les modifier après la construction : les enregistrements modélisent des objets-valeurs immuables.

record Money(long cents, String currency) {}

Money price = new Money(999, "USD");
// price.cents = 500; // Compile error — final field!

// To "update" a record, create a new one
Money discounted = new Money(price.cents() - 100, price.currency());
System.out.println(discounted); // Money[cents=899, currency=USD]

Les enregistrements n’étendent qu’une seule classe

Les enregistrements étendent implicitement java.lang.Record et ne peuvent pas étendre d’autres classes. Ils peuvent implémenter des interfaces.

interface Describable { String describe(); }

record Circle(double radius) implements Describable {
    public String describe() {
        return String.format("Circle with radius %.1f", radius);
    }

    public double area() {
        return Math.PI * radius * radius;
    }
}

Circle c = new Circle(5.0);
System.out.println(c.describe()); // Circle with radius 5.0
System.out.printf("Area: %.2f%n", c.area()); // Area: 78.54

Les enregistrements dans les collections

Comme les enregistrements implémentent correctement equals et hashCode en fonction de tous leurs composants, ils peuvent servir correctement de clés de mappage et d’éléments de Set.

import java.util.*;

record Coordinate(int row, int col) {}

Map<Coordinate, String> grid = new HashMap<>();
grid.put(new Coordinate(0, 0), "Origin");
grid.put(new Coordinate(1, 2), "Target");

// Lookup with equal-valued record works correctly
System.out.println(grid.get(new Coordinate(0, 0))); // Origin
System.out.println(grid.get(new Coordinate(1, 2))); // Target

Set<Coordinate> visited = new HashSet<>();
visited.add(new Coordinate(3, 3));
System.out.println(visited.contains(new Coordinate(3, 3))); // true

Les enregistrements comme objets de transfert de données

Les enregistrements sont idéaux pour les objets de transfert de données (DTO) dans les interfaces REST : ils transportent les données entre les couches sans comportement.

record CreateUserRequest(String email, String displayName, String plan) {}

record UserResponse(long id, String email, String displayName,
                    String plan, String createdAt) {}

// Simulating a service call
static UserResponse createUser(CreateUserRequest req) {
    long id = 42L;
    return new UserResponse(id, req.email(), req.displayName(),
        req.plan(), java.time.Instant.now().toString());
}

CreateUserRequest req = new CreateUserRequest("alice@example.com", "Alice", "PRO");
UserResponse resp = createUser(req);
System.out.println(resp);

Déstructuration des enregistrements

Les enregistrements s’associent très bien à la reconnaissance de motifs. Vous pouvez les déstructurer dans des expressions de sélection (Java 21+).

sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}

static double area(Shape s) {
    return switch (s) {
        case Circle(double r)            -> Math.PI * r * r;
        case Rectangle(double w, double h) -> w * h;
        case Triangle(double b, double h) -> 0.5 * b * h;
    };
}

System.out.printf("%.2f%n", area(new Circle(5)));         // 78.54
System.out.printf("%.2f%n", area(new Rectangle(4, 6)));   // 24.00

Sérialisation des enregistrements

Les enregistrements implémentent naturellement Serializable lorsqu’ils sont déclarés comme sérialisables. Ils fonctionnent immédiatement avec les bibliothèques JSON (Jackson, Gson).

// With Jackson (add @JsonProperty if needed)
import com.fasterxml.jackson.databind.ObjectMapper;

record OrderSummary(String orderId, double total, String status) {}

ObjectMapper mapper = new ObjectMapper();
OrderSummary order = new OrderSummary("ORD-001", 149.99, "SHIPPED");

String json = mapper.writeValueAsString(order);
System.out.println(json);
// {"orderId":"ORD-001","total":149.99,"status":"SHIPPED"}

OrderSummary restored = mapper.readValue(json, OrderSummary.class);
System.out.println(order.equals(restored)); // true

Enregistrements imbriqués

Les enregistrements peuvent contenir d’autres enregistrements comme composants, ce qui permet de construire des graphes riches d’objets immuables.

record Address(String street, String city, String country) {}
record Customer(long id, String name, Address address) {}

Address addr = new Address("123 Main St", "New York", "US");
Customer customer = new Customer(1L, "Alice", addr);

System.out.println(customer.name());              // Alice
System.out.println(customer.address().city());   // New York
System.out.println(customer);                    // Customer[id=1, name=Alice, address=Address[street=123 Main St, city=New York, country=US]]

Limites des enregistrements

Voici certaines restrictions à connaître :

  • Impossible d’étendre d’autres classes (les enregistrements étendent implicitement la classe de base)
  • Les composants sont toujours définitifs : aucun état mutable
  • Impossible de déclarer des champs d’instance en dehors de la liste des composants
  • Impossible d’être abstraits
// Records CAN have static fields and methods
record Temperature(double celsius) {
    static final double ABSOLUTE_ZERO = -273.15;

    public double toFahrenheit() {
        return celsius * 9.0/5.0 + 32;
    }

    public static Temperature fromFahrenheit(double f) {
        return new Temperature((f - 32) * 5.0/9.0);
    }
}
System.out.println(Temperature.fromFahrenheit(98.6)); // Temperature[celsius=37.0]

Vérification rapide

Quels membres le compilateur Java génère-t-il automatiquement pour un enregistrement ?

Récapitulatif : présentation des enregistrements

À retenir :

  • Les enregistrements déclarent des porteurs de données immuables avec un minimum de code répétitif
  • Éléments générés automatiquement : constructeur canonique, accesseurs, equals, hashCode et toString
  • Les composants sont définitifs : les enregistrements sont immuables par conception
  • Les enregistrements peuvent implémenter des interfaces, mais pas étendre de classes
  • Ils sont parfaits pour les objets de transfert de données, les objets-valeurs et les réponses d’interface de programmation
  • Ils fonctionnent correctement comme clés de HashMap et éléments de HashSet grâce à l’égalité structurelle

Questions Fréquemment Posées

La leçon « Découvrir les records » est-elle gratuite ?

Oui — le texte complet de « Découvrir les records » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Découvrir les records » ?

Déclarez des records comme conteneurs de données immuables et concis, puis comprenez leurs membres générés automatiquement. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Java Academy ?

Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Découvrir les records » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?

Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Découvrir les records
  2. Constructeurs compacts et validation
  3. Méthodes personnalisées dans les records
  4. Records, classes et Lombok
← Retour à Java Academy