J'ai trouvé quelques références ( par exemple ) qui suggèrent d'en utiliser final
autant que possible et je me demande à quel point c'est important. Ceci est principalement dans le contexte des paramètres de méthode et des variables locales, pas des méthodes ou des classes finales. Pour les constantes, cela a un sens évident.
D'une part, le compilateur peut faire quelques optimisations et cela rend l'intention du programmeur plus claire. D'autre part, cela ajoute de la verbosité et les optimisations peuvent être triviales.
Est-ce quelque chose que je devrais faire un effort pour me souvenir?
Réponses:
Obséder pour:
Considérez mais utilisez judicieusement:
Ignorer à moins de se sentir anal:
Paramètres de méthode et variables locales - JE le fais RAREMENT parce que je suis paresseux et que je trouve que cela encombre le code. J'admets pleinement que le marquage des paramètres et des variables locales que je ne vais pas modifier est "plus juste". Je souhaite que ce soit la valeur par défaut. Mais ce n'est pas le cas et je trouve le code plus difficile à comprendre avec les finales partout. Si je suis dans le code de quelqu'un d'autre, je ne vais pas les retirer, mais si j'écris un nouveau code, je ne les insérerai pas. Une exception est le cas où vous devez marquer quelque chose comme final pour pouvoir y accéder depuis une classe interne anonyme.
Edit: notez qu'un cas d'utilisation où les variables locales finales sont en fait très utiles comme mentionné par @ adam-gent est lorsque la valeur est assignée à la var dans les branches
if
/else
.la source
final
par défaut. Vous ne remarquerez peut-être pas les avantages à moins d'utiliser un IDE Java vraiment moderne (c'est-à-dire IDEA).final
classes / méthodes. Par exemple, si une méthode finale déclare lever une exception vérifiée mais ne la lance jamais réellement, IDEA vous le dira et vous pourrez supprimer l'exception de lathrows
clause. Parfois, vous pouvez également trouver des méthodes entières inutilisées, ce qui est détectable lorsqu'elles ne peuvent pas être remplacées.Non, si vous utilisez Eclipse, car vous pouvez configurer une action de sauvegarde pour ajouter automatiquement ces modificateurs finaux pour vous. Ensuite, vous obtenez les avantages pour moins d'efforts.
la source
Les avantages de «final» au moment du développement sont au moins aussi importants que les avantages à l'exécution. Il informe les futurs éditeurs du code de vos intentions.
Marquer une classe comme "finale" indique que vous n'avez pas fait d'effort lors de la conception ou de l'implémentation de la classe pour gérer l'extension correctement. Si les lecteurs peuvent apporter des modifications à la classe, et veulent supprimer le modificateur "final", ils peuvent le faire à leurs propres risques. C'est à eux de s'assurer que la classe gérera bien l'extension.
Marquer une variable "finale" (et l'affecter dans le constructeur) est utile avec l'injection de dépendances. Il indique le caractère «collaborateur» de la variable.
Marquer une méthode comme "finale" est utile dans les classes abstraites. Il délimite clairement où se trouvent les points d'extension.
la source
J'utilise
final
tout le temps pour rendre Java plus basé sur l'expression. Voir les conditions de Java (if,else,switch
) ne sont pas basées sur des expressions, ce que j'ai toujours détesté surtout si vous êtes habitué à la programmation fonctionnelle (c'est-à-dire ML, Scala ou Lisp).Ainsi, vous devriez essayer de toujours (IMHO) utiliser les variables finales lors de l'utilisation des conditions.
Laisse moi te donner un exemple:
Maintenant, si ajoutez une autre
case
instruction et ne définissez pas,name
le compilateur échouera. Le compilateur échouera également si vous n'interrompez pas tous les cas (que vous définissez la variable). Cela vous permet de rendre Java très similaire auxlet
expressions de Lisp et de faire en sorte que votre code ne soit pas massivement indenté (à cause des variables de portée lexicale).Et comme @Recurse l'a noté (mais apparemment -1 moi), vous pouvez faire ce qui précède sans faire
String name
final
pour obtenir l'erreur du compilateur (ce que je n'ai jamais dit que vous ne pouviez pas) mais vous pourriez facilement faire disparaître l'erreur du compilateur en définissant le nom après le commutateur déclaration qui jette la sémantique de l'expression ou pire oubliebreak
auquel vous ne pouvez pas provoquer d'erreur (malgré ce que dit @Recurse) sans utiliserfinal
:En raison du nom du paramètre de bogue (en plus d'oublier à
break
quel autre bogue), je peux maintenant faire ceci accidentellement:La variable finale force une seule évaluation de ce que le nom devrait être. Similaire à la façon dont une fonction qui a une valeur de retour doit toujours renvoyer une valeur (en ignorant les exceptions), le bloc de commutation de nom devra résoudre le nom et donc lié à ce bloc de commutation, ce qui facilite la refactorisation de morceaux de code (par exemple, refactor Eclipe: méthode d'extraction) .
Ce qui précède dans OCaml:
L'
match ... with ...
évaluation comme une fonction c'est-à-dire une expression. Remarquez à quoi cela ressemble à notre instruction switch.Voici un exemple de schéma (raquette ou poulet):
la source
else if (...)
en unif(...)
et ainsi réinitialisé la variable. Je lui ai montré que cela ne serait jamais arrivé avec une dernière variable. Fondamentalementfinal
, vous oblige à affecter la variable une et une seule fois ... donc: PJ'ai trouvé des paramètres de méthode de marquage et des locaux
final
utiles comme une aide à la refactorisation lorsque la méthode en question est un désordre incompréhensible de plusieurs pages. Saupoudrezfinal
généreusement, voyez quelles erreurs "ne peut pas affecter à la variable finale" le compilateur (ou votre IDE) lève, et vous découvrirez peut-être pourquoi la variable appelée "data" finit par être nulle même si plusieurs commentaires (obsolètes) jurent que cela peut ça n'arrive pas.Ensuite, vous pouvez corriger certaines des erreurs en remplaçant les variables réutilisées par de nouvelles variables déclarées plus proches du point d'utilisation. Ensuite, vous trouvez que vous pouvez envelopper des parties entières de la méthode dans des accolades de portée, et tout à coup vous êtes à une pression de touche IDE loin de "Extraire la méthode" et votre monstre est devenu plus compréhensible.
Si votre méthode n'est pas déjà une épave impossible à entretenir, je suppose qu'il pourrait être utile de rendre les choses définitives pour décourager les gens de les transformer en épave; mais si c'est une méthode courte (voir: pas impossible à maintenir) alors vous risquez d'ajouter beaucoup de verbosité. En particulier, les signatures de fonction Java sont suffisamment difficiles pour contenir 80 caractères sans en ajouter six de plus par argument!
la source
final
paramètre avant chaque.Eh bien, tout dépend de votre style ... si vous AIMEZ voir la finale alors que vous ne modifierez pas la variable, utilisez-la. Si vous N'AIMEZ PAS le voir ... alors laissez-le de côté.
Personnellement, j'aime le moins de verbosité possible, j'ai donc tendance à éviter d'utiliser des mots clés supplémentaires qui ne sont pas vraiment nécessaires.
Je préfère les langages dynamiques, donc ce n'est probablement pas une surprise que j'aime éviter la verbosité.
Donc, je dirais simplement de choisir la direction dans laquelle vous vous penchez et de suivre (quel que soit le cas, essayez d'être cohérent).
En remarque, j'ai travaillé sur des projets qui utilisent et n'utilisent pas un tel modèle, et je n'ai vu aucune différence dans la quantité de bogues ou d'erreurs ... Je ne pense pas que ce soit un modèle qui va énormément améliorez votre nombre de bogues ou quoi que ce soit, mais encore une fois, c'est du style, et si vous aimez exprimer l'intention de ne pas le modifier, alors continuez et utilisez-le.
la source
Il est utile dans les paramètres d'éviter de changer la valeur du paramètre par accident et d'introduire un bug subtil. J'ignore cette recommandation mais après avoir passé environ 4 heures. dans une méthode horrible (avec des centaines de lignes de code et de multiples fors, des if imbriqués et toutes sortes de mauvaises pratiques), je vous recommanderais de le faire.
Bien sûr, dans un monde parfait, cela n'arriverait pas, mais ... eh bien ... parfois vous devez prendre en charge d'autres codes. :(
la source
Si vous écrivez une application que quelqu'un devra lire le code après, disons, 1 an, alors oui, utilisez final sur une variable qui ne devrait pas être modifiée tout le temps. En faisant cela, votre code sera plus «auto-documenté» et vous réduirez également la chance pour les autres développeurs de faire des choses stupides comme utiliser une constante locale comme variable temporaire locale.
Si vous écrivez du code jetable, alors, non, ne vous souciez pas d'identifier toutes les constantes et de les rendre définitives.
la source
J'utiliserai final autant que possible. Cela signalera si vous modifiez involontairement le champ. J'ai également défini les paramètres de méthode sur final. Ce faisant, j'ai attrapé plusieurs bogues du code que j'ai pris en charge lorsqu'ils essaient de «définir» un paramètre en oubliant les passes Java par valeur.
la source
La question de savoir si cela est évident n'est pas clair, mais rendre un paramètre de méthode final n'affecte que le corps de la méthode. Il ne transmet AUCUNE information intéressante sur les intentions de la méthode à l'invocateur. L'objet transmis peut toujours être muté dans la méthode (les finals ne sont pas des consts), et la portée de la variable est dans la méthode.
Pour répondre à votre question précise, je ne prendrais pas la peine de rendre une instance ou une variable locale (y compris les paramètres de méthode) finale à moins que le code ne l'exige (par exemple, la variable est référencée à partir d'une classe interne), ou pour clarifier une logique vraiment compliquée.
Par exemple, les variables, je les rendrais définitives si elles sont logiquement des constantes.
la source
Il existe de nombreuses utilisations de la variable
final
. En voici quelques-unsConstantes finales
Cela peut être utilisé pour d'autres parties de vos codes, ou accédé par d'autres classes, de cette façon si jamais vous changiez la valeur, vous n'auriez pas à les changer une par une.
Variables finales
Dans cette classe, vous créez une variable finale de portée qui ajoute un préfixe au paramètre environmentKey. Dans ce cas, la variable finale n'est finale que dans le périmètre d'exécution, qui est différent à chaque exécution de la méthode. Chaque fois que la méthode est entrée, la finale est reconstruite. Dès qu'il est construit, il ne peut pas être modifié pendant la portée de l'exécution de la méthode. Cela vous permet de fixer une variable dans une méthode pour la durée de la méthode. voir ci-dessous:
Constantes finales
Ceux-ci sont particulièrement utiles lorsque vous avez de très longues lignes de codes, et cela générera une erreur du compilateur afin que vous ne vous heurtiez pas à une erreur logique / commerciale lorsque quelqu'un change accidentellement des variables qui ne devraient pas être modifiées.
Collections finales
Cas différent lorsque nous parlons de collections, vous devez les définir comme non modifiables.
sinon, si vous ne le définissez pas comme non modifiable:
Les classes finales et les méthodes finales ne peuvent pas être étendues ou écrasées respectivement.
MODIFIER: POUR RÉPONDRE AU PROBLÈME DE CLASSE FINALE CONCERNANT L'ENCAPSULATION:
Il y a deux façons de rendre une classe finale. La première consiste à utiliser le mot-clé final dans la déclaration de classe:
La deuxième façon de rendre une classe finale est de déclarer tous ses constructeurs comme privés:
Le marquer comme final vous évite les ennuis si vous découvrez qu'il s'agit réellement d'une finale, pour démontrer regardez cette classe de test. regarde public à première vue.
Malheureusement, comme le seul constructeur de la classe est privé, il est impossible d'étendre cette classe. Dans le cas de la classe Test, il n'y a aucune raison que la classe soit définitive. La classe Test est un bon exemple de la façon dont les classes finales implicites peuvent causer des problèmes.
Vous devez donc le marquer comme final lorsque vous rendez implicitement une classe finale en rendant son constructeur privé.
la source
Un peu de compromis comme vous le mentionnez, mais je préfère l'utilisation explicite de quelque chose à l'utilisation implicite. Cela aidera à éliminer certaines ambiguïtés pour les futurs responsables du code - même si ce n'est que vous.
la source
Si vous avez des classes internes (anonymes) et que la méthode a besoin d'accéder à la variable de la méthode contenant, vous devez avoir cette variable comme finale.
À part cela, ce que vous avez dit est juste.
la source
Utilisez un
final
mot-clé pour une variable si vous créez cette variable commeimmutable
En déclarant la variable comme finale, cela aide les développeurs à exclure d'éventuels problèmes de modification des variables dans un environnement hautement multithread.
Avec la version java 8, nous avons un autre concept appelé "
effectively final variable
". Une variable non finale peut devenir une variable finale.les variables locales référencées à partir d'une expression lambda doivent être finales ou effectivement finales
Jusqu'à Java 7, vous ne pouvez pas utiliser une variable locale non finale dans une classe anonyme, mais à partir de Java 8, vous pouvez
Jetez un œil à cet article
la source
Tout d'abord, le mot-clé final est utilisé pour rendre une variable constante. Constante signifie que cela ne change pas. Par exemple:
Vous déclareriez la variable finale car un centimètre par pouce ne change pas.
Si vous essayez de remplacer une valeur finale, la variable est ce qu'elle a été déclarée en premier. Par exemple:
Il y a une erreur de compilation qui est quelque chose comme:
Si votre variable ne peut pas être déclarée finale ou si vous ne voulez pas la déclarer définitive, essayez ceci:
Cela imprimera:
la source