web-dev-qa-db-fra.com

mot-clé final dans les paramètres de méthode

Je rencontre souvent des méthodes qui ressemblent à ceci:

public void foo(final String a, final int[] b, final Object1 c){
}

Que se passe-t-il si cette méthode est appelée sans lui transmettre les paramètres finaux? c'est-à-dire qu'un objet1 qui est modifié plus tard (donc n'est pas déclaré comme final) peut être passé à cette méthode très bien

124
Aly

Java effectue toujours une copie des paramètres avant de les envoyer aux méthodes. Cela signifie que la finale ne signifie aucune différence pour le code appelant. Cela signifie seulement qu'à l'intérieur de la méthode, les variables ne peuvent pas être réaffectées. (notez que si vous avez un objet final, vous pouvez toujours changer les attributs de l'objet).

159
Thirler

Il existe une circonstance dans laquelle vous êtes obligatoire à le déclarer final - sinon, cela entraînera une erreur de compilation - à savoir, vous les passerez dans des classes anonymes. Exemple de base:

public FileFilter createFileExtensionFilter(final String extension) {
    FileFilter fileFilter = new FileFilter() {
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(extension);
        }
    };

    // What would happen when it's allowed to change extension here?
    // extension = "foo";

    return fileFilter;
}

La suppression du modificateur final entraînerait une erreur de compilation, car il n'est plus garanti que la valeur soit une constante d'exécution. Si vous modifiez la valeur en dehors de la classe anonyme, l'instance de la classe anonyme se comporterait différemment après la création.

77
BalusC

Java est seulement passé par valeur. (ou mieux - passe-référence-par-valeur)

Ainsi, l'argument passé et l'argument dans la méthode sont deux gestionnaires différents pointant vers le même objet (valeur). 

Par conséquent, si vous modifiez l'état de l'objet, il est répercuté sur toutes les autres variables qui le référencent. Mais si vous réaffectez un nouvel objet (valeur) à l'argument, les autres variables pointant sur cet objet (valeur) ne sont pas réaffectées.

51
Bozho

Le mot clé final dans un paramètre de méthode ne signifie absolument rien pour l'appelant. Cela ne signifie également absolument rien pour le programme en cours d'exécution, car sa présence ou son absence ne modifie pas le code intermédiaire. Cela garantit uniquement que le compilateur se plaindra si la variable de paramètre est réaffectée dans la méthode. C'est tout. Mais ça suffit.

Certains programmeurs (comme moi) pensent que c'est une très bonne chose et utilisent final dans presque tous les paramètres. Cela facilite la compréhension d'une méthode longue ou complexe (bien que l'on puisse argumenter que les méthodes longues et complexes doivent être refactorisées.) Il met également en lumière les paramètres de méthode qui not are sont marqués par final.

27
Erick G. Hagstrom

Considérez cette implémentation de foo ():

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}

Comme l'instance Runnable survivrait à la méthode, elle ne serait pas compilée sans le mot clé final - final indique au compilateur qu'il est prudent de prendre une copie de la référence (pour s'y référer ultérieurement). Ainsi, c'est la référence qui est considérée comme finale, pas la valeur . En d'autres termes: en tant qu'appelant, vous ne pouvez rien gâcher ...

17
Rahel Lüthy

Si vous déclarez un paramètre comme final, vous ne pouvez pas en modifier la valeur.

class Bike11 {  
    int cube(final int n) {  
        n=n+2;//can't be changed as n is final  
        n*n*n;  
     }  
    public static void main(String args[]) {  
        Bike11 b=new Bike11();  
        b.cube(5);  
    }  
}   

Sortie: erreur de compilation

Pour plus de détails, s'il vous plaît visitez mon blog: http://javabyroopam.blogspot.com

2
Roopam

final signifie que vous ne pouvez pas changer la valeur de cette variable une fois assignée.

Dans le même temps, l’utilisation de final pour les arguments de ces méthodes signifie que cela ne permettra pas au programmeur de changer leur valeur lors de l’exécution de la méthode . Cela signifie simplement qu’à l’intérieur de la méthode, final les variables ne peuvent pas être réaffectées.

1
SilentKnight

le mot clé final dans le paramètre d'entrée de la méthode n'est pas nécessaire. Java crée une copie de la référence à l'objet, ainsi, mettre final ne rend pas l'objet final, mais simplement la référence, ce qui n'a pas de sens.

0
ttati

@stuXnet, je pourrais faire valoir l'argument opposé exact. Si vous passez un objet à une fonction et que vous modifiez les propriétés de l'objet transmis, l'appelant de la fonction verra la valeur modifiée dans sa variable. Cela implique un système passe par référence, et non par valeur.

Ce qui est déroutant, c’est que la définition passe par valeur ou passe par référence dans un système où l’utilisation de pointeurs est complètement masquée pour l’utilisateur final. 

Java n'est définitivement PAS passe par valeur, car cela signifie que l'on pourrait muter l'objet passé et que l'original ne serait pas affecté. 

Notez que vous ne pouvez pas muter les primitives, vous pouvez uniquement les affecter à des variables. Donc, tester un Pass par référence ou par valeur en utilisant des primitives n'est pas un test. 

Ce que vous ne pouvez pas faire en Java avec d’autres langages, c’est de réaffecter les variables de l’appelant à une nouvelle valeur car il n’existe aucun pointeur en Java. 

0
Armand

Les chaînes étant immuables, vous ne pouvez pas modifier la chaîne ultérieurement (vous pouvez uniquement faire pointer la variable contenant l'objet String sur un autre objet String).

Cependant, ce n'est pas la raison pour laquelle vous pouvez lier une variable à un paramètre final. Toutes les vérifications du compilateur indiquent que le paramètre n'est pas réaffecté dans la méthode. C'est bon pour la documentation, sans doute un bon style et peut même aider à optimiser le code d'octet pour plus de rapidité (bien que cela ne semble pas faire beaucoup en pratique). 

Mais même si vous réaffectez un paramètre dans une méthode, l'appelant ne le remarque pas, car Java effectue tous les paramètres en les transmettant par valeur. Après la séquence

  a = someObject();
  process(a);

les champs de a peuvent avoir changé, mais a reste le même objet qu’il était auparavant. Dans les langues avec référence, cela peut ne pas être vrai.

0
Kilian Foth