CodeGym /Blog Java /Random-FR /Parlons du mot clé final en Java
Auteur
Oleksandr Miadelets
Head of Developers Team at CodeGym

Parlons du mot clé final en Java

Publié dans le groupe Random-FR
Java a ce mot-clé — final. Il peut être appliqué aux classes, aux méthodes, aux variables (y compris les paramètres de méthode). Pour une classe, le mot-clé final signifie que la classe ne peut pas avoir de sous-classes, c'est-à-dire que l'héritage est interdit... Ceci est utile lors de la création d'objets immuables (inchangeables). Par exemple, la classe String est déclarée comme final.

    public final class String {
    }
    
    class SubString extends String { // Compilation error
    }
Je dois également noter que le modificateur final ne peut pas être appliqué aux classes abstraites (celles avec le mot-clé abstract), car ce sont des concepts mutuellement exclusifs. Pour une méthode finale, le modificateur signifie que la méthode ne peut pas être redéfinie dans les sous-classes. Ceci est utile lorsque nous voulons empêcher la modification de l'implémentation d'origine.

    public class SuperClass {
        public final void printReport() {
            System.out.println("Report");
        }
    }

    class SubClass extends SuperClass { 
        public void printReport() { //Compilation error
            System.out.println("MyReport");
        }
    }
Pour les variables de type primitif, le mot-clé final signifie que la valeur, une fois affectée, ne peut pas être modifiée. Pour les variables de référence, cela signifie qu'après l'affectation d'un objet, vous ne pouvez pas modifier la référence à cet objet. C'est important! La référence ne peut pas être modifiée, mais l'état de l'objet peut être modifié. Java 8 a introduit un nouveau concept : effectivement final. Il s'applique uniquement aux variables (y compris les paramètres de méthode). L'essentiel est que malgré l'absence manifeste du mot-clé final, la valeur de la variable ne change pas après l'initialisation. En d'autres termes, le mot clé final peut être appliqué à une telle variable sans erreur de compilation. En effet, les variables finales peuvent être utilisées dans des classes locales (classes internes locales), des classes anonymes (classes internes anonymes) et des flux (API Stream).

        public void someMethod() {
            // In the example below, both a and b are effectively final, since they are assigned values only once:
            int a = 1;
            int b;
            if (a == 2) b = 3;
            else b = 4;
            // c is NOT effectively final since its value changes
            int c = 10;
            c++;
            
            Stream.of(1, 2).forEach(s-> System.out.println(s + a)); // OK
            Stream.of(1, 2).forEach(s-> System.out.println(s + c)); // Compilation error
        }
Maintenant, faisons une petite interview. Après tout, l'objectif de suivre le cours CodeGym est de devenir développeur Java et de trouver un travail intéressant et bien rémunéré. Alors, commençons.
  1. Que dire d'un tableau déclaré final ?

  2. On sait que la classe String est immuable : la classe est déclarée final. Une valeur de chaîne est stockée dans un tableau de caractères marqué avec le mot-clé final.


public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

Peut-on remplacer la valeur d'un objet String (sans changer la référence à l'objet) ? Ce sont de vraies questions d'entretien. Et la pratique montre que de nombreux candidats n'y répondent pas correctement. Comprendre comment le mot-clé final est utilisé, en particulier pour les variables de référence, est très important. Pendant que vous envisagez cela, je vais faire une petite demande à l'équipe de CodeGym. Veuillez donner à l'éditeur de texte la possibilité d'ajouter un bloc dont le contenu peut être affiché/masqué lorsque vous cliquez dessus. Réponses:
  1. Un tableau est un objet, donc le mot clé final signifie qu'une fois qu'une référence au tableau est assignée, la référence ne peut pas être changée. Cela dit, vous pouvez changer l'état de l'objet.

    
            final int[] array = {1, 2, 3, 4, 5};
            array[0] = 9;	 // OK, because we're changing the contents of the array: {9, 2, 3, 4, 5}
            array = new int[5]; // Compilation error
    
  2. Oui nous pouvons. L'essentiel est de comprendre ce que signifie le mot-clé final épineux lorsqu'il est utilisé avec des objets. L'API Reflection peut être utilisée pour remplacer des valeurs.


import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        // Get the String class's value field
        Field field = value.getClass().getDeclaredField("value");
        // Make it mutable
        field.setAccessible(true);
        // Set a new value
        field.set(value, "CodeGym".toCharArray());

        System.out.println(value);

        /* Output:
         * Old value
         * CodeGym
         */
    }
}
Veuillez noter que si nous avions essayé de changer la variable finale d'un type primitif de cette manière, rien ne se serait produit. Je vous propose de vous en convaincre : créez par exemple une classe Java avec un champ int final et essayez de modifier sa valeur à l'aide de l'API Reflection. Bonne chance à tous!
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION