web-dev-qa-db-fra.com

Utilisation des variables locales finales dans java

Je me demandais s'il était possible d'utiliser des variables locales finales. Les variables ne sont de toute façon pas remplacées lorsque l'héritage entre en jeu. Par exemple un code simple comme ci-dessous

public static void main(String args[]) {
    final String data = "Hello World!";
    System.out.println(data);
}

L'exemple est assez simple et peut ne pas être un code pertinent mais la question est plus générique J'ai vu beaucoup de codes (tous incorporés dans la fonction principale qui ont des variables locales finales) Y a-t-il une utilité de déclarer des variables locales comme autres finales que qu'ils ne peuvent pas être modifiés dans la même fonction elle-même?

31
Aniket Thakur

Premièrement, la partie sur les variables étant "surchargées" - final a deux significations très différentes. Pour les classes et les méthodes, il s'agit d'héritage; pour les variables, il s'agit d'être en lecture seule.

Il existe une "caractéristique" importante des variables locales finales: elles peuvent être utilisées dans des classes internes locales (généralement anonymes). Les variables locales non finales ne peuvent pas l'être. C'est l'utilisation principale de final pour les variables locales, d'après mon expérience.

public void foo() {
    final String x = "hello";
    String y = "there";

    Runnable runnable = new Runnable() {
        @Override public void run() {
            System.out.println(x); // This is valid
            System.out.println(y); // This is not
        }
    };
    runnable.run();
}

Notez que pour une question de style, certaines personnes aiment utiliser final même lorsqu'elles pas capturent la variable dans une classe interne locale. Je serais certainement à l'aise avec final étant la valeur par défaut, mais un modificateur différent pour "non final", mais je trouve que l'ajout explicite du modificateur partout est trop distrayant.

59
Jon Skeet

les variables locales finales sont accessibles à partir de sous-classes internes anonymes, contrairement aux variables locales non finales.

9
John Smith

Oui, l'utilisabilité est: - les variables finales locales sont accessibles par la classe interne de la méthode. Puisque les variables locales vivent sur la pile et n'existent que pour la durée de vie de la méthode, mais l'objet de classe interne peut vivre plus longtemps, de sorte que la classe interne ne peut accéder à aucune variable locale non finale. Mais une fois que la variable est finale, la classe interne s'assure que la valeur ne changera pas, donc elle conserve une copie privée de la variable locale finale pour utilisation.

8
Krushna

Réponse parfaite Jon Skeet mais il y a un autre (petit) avantage des variables finales.

Le compilateur s'assurera que la variable finale est définie une seule fois.

Disons que vous devez initialiser une variable et que le calcul de la valeur est complexe (plusieurs if-then-else dans if-then-else). Vous pouvez écrire du code qui n'initialise pas la variable dans certaines conditions (ou l'initialiser deux fois). Bien sûr, c'est un bug. Rendre la variable finale permettra au compilateur de vérifier que la variable finale est définie une fois et une seule fois. Vous saurez donc rapidement si vous avez un bug.

Comme je l'ai dit, peu d'avantages mais toujours pratique.

5
Algiz

oui il y a, un petit exemple où nous pourrions normalement l'utiliser -

Extrait:

final Boolean data = Boolean.TRUE;
button.addListener(SWT.Selection, new Listener() {
    public void handleEvent(Event event) {
        if (data ) {
                     ....
                }
        }
});

C'est un exemple d'utilisation avec des classes internes anonymes. Si vous voulez utiliser votre variable locale à l'intérieur des cals internes, vous devez faire final.

5

Utilisation des dernières variables locales en Java

final les champs, les paramètres et les variables locales sont lecture seule (signifie l'identité de l'objet, pas son état).

4
Premraj

Vous pouvez utiliser le mot clé final pour la lisibilité et vous assurer qu'il n'est pas modifié ou dans des classes anonymes comme ici:

    final String s = "hi";
    new Thread(new Runnable() {
        @Override
        public void run() {
            // can use s variable here
        }
    }).start();
3
Tala

Il indique aux autres programmeurs que celui qui l'a écrit savait que la valeur de data ne devrait pas changer une fois attribuée. C'est une bonne habitude à mon avis, en particulier en déclarant les variables de paramètre comme final.

3
Sajal Dutta