Menu
CoddyTech

Le mot-clé final

Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 13 sur 87.

Le mot-clé final en Java empêche toute modification. Il peut être appliqué aux variables, aux méthodes et aux classes, avec un effet différent dans chaque cas.

Appliqué à une variable, final en fait une constante : une fois assignée, sa valeur ne peut pas changer :

public class Circle {
    private final double PI = 3.14159;
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;  // Peut être affecté une seule fois dans le constructeur
    }
    
    public void setRadius(double r) {
        // this.radius = r;  // Erreur ! Impossible de réaffecter une variable final
    }
}

Une variable final doit être initialisée soit lors de sa déclaration, soit dans le constructeur. Après cela, toute tentative de lui réaffecter une valeur provoque une erreur de compilation.

Pour les types référence, final signifie que la référence ne peut pas pointer vers un autre objet, mais que le contenu de l’objet peut tout de même changer :

private final StringBuilder name = new StringBuilder("John");

// name = new StringBuilder("Jane");  // Erreur ! Impossible de réaffecter
name.append(" Doe");  // OK ! Le contenu de l’objet peut changer

Utiliser final avec des champs communique clairement l’intention : cela indique aux autres développeurs que cette valeur ne doit jamais changer après son initialisation. C’est particulièrement utile pour les valeurs de configuration, les identifiants ou toute donnée qui doit rester constante pendant toute la durée de vie d’un objet.

Une final méthode ne peut pas être redéfinie dans une sous-classe :

class Base {
    public final void greet() {
        System.out.println("Hi");
    }
}
class Child extends Base {
    // public void greet() { }  // Erreur ! greet() est final dans Base
}

Une classe final ne peut pas du tout être étendue. String est une classe finale, donc aucune classe ne peut l'étendre :

final class Config { }
// class MyConfig extends Config { }  // Erreur ! Config est final
challenge icon

Défi

Facile

Construisons un système d’inscription des étudiants Student qui utilise le mot-clé final pour protéger les données qui ne doivent jamais changer après l’inscription d’un étudiant.

Tu vas créer deux fichiers pour organiser ton code :

  • Student.java : crée une classe Student dans laquelle certaines informations sont verrouillées de façon permanente une fois définies :
    • Un champ final studentId (String) — attribué à la création et qui ne peut jamais changer
    • Un champ final enrollmentYear (int) — l’année d’inscription de l’étudiant, également permanente
    • Un champ privé ordinaire name (String) — peut être mis à jour si l’étudiant change de nom
    • Un constructeur qui prend les trois valeurs et initialise les champs
    • Un accesseur getStudentId() pour l’identifiant de l’étudiant
    • Un accesseur getEnrollmentYear() pour l’année d’inscription
    • Un accesseur getName() et un mutateur setName() pour le nom
    • Une méthode getInfo() qui renvoie : "ID: [studentId] | Name: [name] | Enrolled: [enrollmentYear]"
  • Main.java : crée un objet Student, puis mets à jour son nom et affiche ses informations. Tu recevras quatre entrées : l’identifiant de l’étudiant, le nom initial, l’année d’inscription et un nouveau nom à définir. Affiche deux lignes :
    • Les informations de l’étudiant avant le changement de nom
    • Les informations de l’étudiant après le changement de nom

Tu recevras quatre entrées dans l’ordre suivant : studentId (String), name (String), enrollmentYear (int) et newName (String).

Remarque comment les champs final protègent l’identifiant de l’étudiant et son année d’inscription : ce sont des informations permanentes qui ne doivent pas changer, tandis que le nom peut être mis à jour à l’aide de son mutateur.

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 studentId = scanner.nextLine();
        String name = scanner.nextLine();
        int enrollmentYear = scanner.nextInt();
        scanner.nextLine(); // consommer le caractère de nouvelle ligne
        String newName = scanner.nextLine();
        
        // TODO: Créer un objet Student avec les valeurs initiales
        
        // TODO: Afficher les informations de l’étudiant avant le changement de nom
        
        // TODO: Mettre à jour le nom de l’étudiant à l’aide du setter
        
        // TODO: Afficher les informations de l’étudiant après le changement de nom
    }
}
quiz iconTestez-vous

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

Entraînez-vous par vous-même : Compilateur Java en ligne