Je considère final
dans les paramètres de méthode et les variables locales le code de bruit. Les déclarations de méthodes Java peuvent être assez longues (surtout avec les génériques) - il n'est pas nécessaire de les créer plus longtemps.
Si les tests unitaires sont écrits correctement, l’attribution de paramètres «nocifs» sera prise en compte, il ne devrait donc jamais y avoir de problème. La clarté visuelle est plus importante que d'éviter un bug possible qui n'est pas détecté car la couverture de vos tests unitaires est insuffisante.
Des outils tels que FindBugs et CheckStyle peuvent être configurés pour interrompre la construction si une affectation est faite à des paramètres ou à des variables locales, si de telles choses vous tiennent à coeur.
Bien sûr, si vous devez les rendre finales, par exemple parce que vous utilisez la valeur dans une classe anonyme, alors pas de problème, c'est la solution la plus simple et la plus propre.
Outre l'effet évident d'ajouter des mots-clés supplémentaires à vos paramètres et de les camoufler ainsi à mon humble avis, l'ajout des paramètres de méthode finaux peut souvent rendre le code du corps de la méthode moins lisible, ce qui aggrave le code - d'être "bon", code doit être aussi lisible et aussi simple que possible. Pour un exemple artificiel, disons que j'ai une méthode qui doit fonctionner sans distinction de casse.
Sans final
:
public void doSomething(String input) {
input = input.toLowerCase();
// do a few things with input
}
Facile. Nettoyer. Tout le monde sait ce qui se passe.
Maintenant avec 'final', option 1:
public void doSomething(final String input) {
final String lowercaseInput = input.toLowerCase();
// do a few things with lowercaseInput
}
Bien que définir les paramètres final
empêche le codeur d’ajouter du code parce qu’il pense ne pas travailler avec la valeur originale, il existe un risque équivalent que le code plus bas puisse utiliser à la input
place lowercaseInput
, ce qu’il ne devrait pas et contre lequel on ne peut pas se protéger, car vous pouvez " t le sortir de la portée (ou même assigner null
à input
si cela pourrait même aider de toute façon).
Avec 'final', option 2:
public void doSomething(final String input) {
// do a few things with input.toLowerCase()
}
Nous venons tout juste de créer encore plus de bruit de code et d’avoir à invoquer toLowerCase()
n fois.
Avec 'final', option 3:
public void doSomething(final String input) {
doSomethingPrivate(input.toLowerCase());
}
/** @throws IllegalArgumentException if input not all lower case */
private void doSomethingPrivate(final String input) {
if (!input.equals(input.toLowerCase())) {
throw new IllegalArgumentException("input not lowercase");
}
// do a few things with input
}
Parlez du bruit de code. Ceci est une épave de train. Nous avons une nouvelle méthode, un bloc d'exception requis, car un autre code peut ne pas l'appeler correctement. Plus de tests unitaires pour couvrir l'exception. Tout pour éviter une ligne simple, et à mon humble avis préférable et sans danger,.
Il y a également le problème que les méthodes ne devraient pas être si longues que vous ne pouvez pas facilement les assimiler visuellement et savoir en un coup d'œil qu'une affectation à un paramètre a eu lieu.
Je pense que c’est une bonne pratique / style que, si vous affectez un paramètre, vous le fassiez au début de la méthode, de préférence en première ligne ou juste après la vérification de base des entrées, en le remplaçant efficacement pour toute la méthode, ce qui a un effet cohérent au sein de la méthode. méthode. Les lecteurs savent qu’ils s’attendent à ce que toute tâche soit évidente (à proximité de la déclaration de signature) et dans un endroit cohérent, ce qui atténue considérablement le problème que l’ajout de final tente d’éviter. En fait, j'assigne rarement des paramètres, mais si je le fais, je le fais toujours au sommet d'une méthode.
Notez également que final
ne vous protège pas réellement comme cela peut paraître au premier abord:
public void foo(final Date date) {
date.setTime(0);
// code that uses date
}
final
ne vous protège pas complètement sauf si le type de paramètre est primitif ou immuable.