Quelle différence que final
fait entre le code ci-dessous. Y a-t-il un avantage à déclarer les arguments comme final
.
public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){
return ....
}
public String changeTimezone(final Timestamp stamp, final Timezone fTz,
final Timezone toTz){
return ....
}
Un paramètre de méthode formel étant une variable locale, vous ne pouvez y accéder à partir des classes anonymes internes que si elles sont déclarées comme finales.
Cela vous évite de déclarer une autre variable finale locale dans le corps de la méthode:
void m(final int param) {
new Thread(new Runnable() {
public void run() {
System.err.println(param);
}
}).start();
}
Extrait de Le dernier mot sur le mot-clé final
Paramètres finaux
L'exemple suivant déclare les paramètres finaux:
public void doSomething(final int i, final int j)
{
// cannot change the value of i or j here...
// any change would be visible only inside the method...
}
final est utilisé ici pour garantir que les deux index i et j ne seront pas réinitialisés accidentellement par la méthode. C'est un moyen pratique de se protéger contre un bug insidieux qui modifie par erreur la valeur de vos paramètres. De manière générale, les méthodes courtes sont un meilleur moyen de se protéger de cette classe d'erreurs, mais les paramètres finaux peuvent être un ajout utile à votre style de codage.
Notez que les paramètres finaux ne sont pas considérés comme faisant partie de la signature de la méthode et sont ignorés par le compilateur lors de la résolution des appels de méthode. Les paramètres peuvent être déclarés définitifs (ou non) sans influence sur la façon dont la méthode est remplacée.
La finale vous empêche d'attribuer une nouvelle valeur à la variable, ce qui peut être utile pour détecter les fautes de frappe. Sur le plan stylistique, vous souhaiterez peut-être conserver les paramètres reçus inchangés et les affecter uniquement aux variables locales, donc final aiderait à appliquer ce style.
Je dois admettre que je me souviens rarement d'utiliser final pour les paramètres, peut-être que je devrais.
public int example(final int basicRate){
int discountRate;
discountRate = basicRate - 10;
// ... lots of code here
if ( isGoldCustomer ) {
basicRate--; // typo, we intended to say discountRate--, final catches this
}
// ... more code here
return discountRate;
}
Cela ne fait pas beaucoup de différence. Cela signifie simplement que vous ne pouvez pas écrire:
stamp = null;
fTz = new ...;
mais vous pouvez toujours écrire:
stamp.setXXX(...);
fTz.setXXX(...);
C'est principalement un indice pour le programmeur de maintenance qui vous suit que vous n'allez pas attribuer une nouvelle valeur au paramètre quelque part au milieu de votre méthode où il n'est pas évident et pourrait donc causer de la confusion.
Le mot-clé final lorsqu'il est utilisé pour les paramètres/variables dans Java marque la référence comme finale. En cas de passage d'un objet à une autre méthode, le système crée une copie de la variable de référence et la transmet au En marquant les nouvelles références comme finales, vous les protégez de toute réaffectation, ce qui est parfois considéré comme une bonne pratique de codage.
Pour le corps de cette méthode, le mot clé final
empêchera les références d'argument d'être réaffectées accidentellement, donnant une erreur de compilation sur ces cas (la plupart des IDE se plaindront immédiatement). Certains diront que l'utilisation de final
en général dans la mesure du possible accélérera les choses, mais ce n'est pas le cas dans les JVM récentes.
C'est juste une construction en Java pour vous aider à définir un contrat et à vous y tenir. Une discussion similaire ici: http://c2.com/cgi/wiki?JavaFinalConsideredEvil =
BTW - (comme le dit le twiki), marquer les arguments comme finaux est généralement redondant si vous suivez de bons principes de programmation et que vous avez fini de réaffecter/redéfinir la référence d'argument entrante.
Dans le pire des cas, si vous redéfinissez la référence args, cela n'affectera pas la valeur réelle transmise à la fonction - car seule une référence a été transmise.
- Dans le passé (avant Java 8 :-))
Explit l'utilisation du mot-clé "final" a affecté l'accessibilité de la variable de méthode pour les classes anonymes internes.
- Dans la langue moderne (Java 8+), une telle utilisation n'est pas nécessaire:
Java a introduit des variables "effectivement définitives". Les variables locales et les paramètres de méthode sont supposés définitifs si le code n'implique pas de changement de valeur de la variable. Donc, si vous voyez un tel mot-clé dans Java8 +, vous pouvez supposer qu'il est inutile. L'introduction de "effectivement final" nous fait taper moins de code lors de l'utilisation de lambdas.
Je parle de marquer les variables et les champs finaux en général - ne s'applique pas seulement aux arguments de méthode. (Le marquage final des méthodes/classes est une toute autre chose).
C'est une faveur pour les lecteurs/futurs responsables de votre code. Avec un nom raisonnable de la variable, il est utile et rassurant pour le lecteur de votre code de voir/comprendre ce que représentent les variables en question - et il est rassurant pour le lecteur que chaque fois que vous voyez la variable dans la même portée, la signification reste la même chose, donc il n'a pas à se gratter la tête pour toujours comprendre ce que signifie une variable dans chaque contexte. Nous avons vu trop d'abus de "réutilisation" des variables, ce qui rend même un court extrait de code difficile à comprendre.