Sobes.tech
Junior

Dans quels cas peut-on utiliser le modificateur final en Java?

sobes.tech IA

Réponse de l'IA

Le modificateur final en Java peut être appliqué à :

  1. Variables :

    • Variables locales : Leur valeur est assignée une fois et ne peut être modifiée après l'initialisation.
    • Champs de classe : La valeur du champ est assignée lors de la déclaration ou dans le constructeur, puis ne peut plus être modifiée.
    • Paramètres de méthode : Le paramètre à l'intérieur de la méthode devient une constante ; il ne peut pas être réaffecté dans le corps de la méthode.

    Appliquer final aux variables garantit :

    • Immutabilité : Garantie que la valeur ne changera pas.
    • Sécurité en multithreading : Les champs final d'une classe sont visibles par tous les threads après la fin du constructeur sans synchronisation supplémentaire.
    • Optimisations du compilateur : Le compilateur peut effectuer certaines optimisations en sachant que la valeur ne changera pas.
  2. Méthodes :

    • Une méthode déclarée comme final ne peut pas être surchargée dans les sous-classes.
    • Cela est utile pour :
      • Prévenir les changements indésirables de comportement : Garantit que la logique de la méthode reste inchangée.
      • Favoriser la composition : Encourage l'utilisation de la composition plutôt que l'héritage.
      • Optimisations possibles du compilateur : Le compilateur peut effectuer un inlining des appels aux méthodes final.
  3. Classes :

    • Une classe déclarée comme final ne peut pas avoir de sous-classes.
    • L'utilisation de final sur une classe sert à :
      • Créer des classes immuables : Par exemple, les classes enveloppe de types primitifs (Integer, String).
      • Protéger la conception : Empêche l'extension qui pourrait violer les invariants de la classe.
      • Augmenter la sécurité : Garantit que le comportement de la classe ne peut pas être modifié par la création de sous-classes.
Application Description Avantages
final champ La valeur est assignée une fois (à la déclaration ou dans le constructeur). Immutabilité, sécurité en multithreading, optimisations.
final paramètre La valeur ne peut pas être modifiée à l'intérieur de la méthode. Signature claire, garantie d'immutabilité du paramètre.
final méthode Ne peut pas être surchargée dans les sous-classes. Prévenir la modification du comportement, encourager la composition, optimisations.
final classe Ne peut pas avoir de sous-classes (interdiction d'héritage). Immutabilité de la classe, protection de la conception, sécurité accrue.

Exemples :

public class Example {
    // champ final de la classe
    private final String name;

    // champ primitif final
    private final int id;

    // champ final, mais peut être référence à différents objets List tant que l'objet n'est pas créé
    // après la création, la référence peut changer, mais pas la référence elle-même
    private final List<String> items;

    // Constante en temps de compilation
    public static final double PI = 3.14159;

    public Example(String name, int id) {
        this.name = name; // assignation au champ final
        this.id = id;     // assignation au champ final
        this.items = new ArrayList<>(); // initialisation du champ final
    }

    // méthode final
    public final void printDetails() {
        System.out.println("Name: " + name + ", ID: " + id);
    }

    // méthode avec paramètre final
    public void addItem(final String item) {
        // item = "nouvel élément"; // erreur de compilation : impossible d'assigner à une variable final
        items.add(item);
    }
}

// classe final
// public final class ImmutableClass {
//     private final int value;
//
//     public ImmutableClass(int value) {
//         this.value = value;
//     }
//
//     public int getValue() {
//         return value;
//     }
// }

// public class SubclassOfImmutable extends ImmutableClass { // erreur de compilation : impossible d'hériter d'une classe final
// }