Considero final
que los parámetros del método y las variables locales son ruido de código. Las declaraciones de métodos Java pueden ser bastante largas (especialmente con los genéricos); no es necesario hacerlas por más tiempo.
Si las pruebas unitarias se escriben correctamente, la asignación de parámetros que es "perjudicial" va a ser recogido, por lo que nunca debería realmente ser un problema. La claridad visual es más importante que evitar un posible error que no se detecta porque las pruebas de su unidad no tienen una cobertura suficiente.
Herramientas como FindBugs y CheckStyle que se pueden configurar para romper la compilación si se realiza una asignación a parámetros o variables locales, si se preocupa profundamente por tales cosas.
Por supuesto, si necesita hacerlos finales, por ejemplo, porque está usando el valor en una clase anónima, entonces no hay problema: esa es la solución más simple y limpia.
Además del efecto obvio de agregar palabras clave adicionales a sus parámetros y, por lo tanto, en mi humilde opinión, camuflarlas, agregar los parámetros finales al método a menudo puede hacer que el código en el cuerpo del método sea menos legible, lo que empeora el código: para ser "bueno", el código debe ser lo más legible y simple posible. Para un ejemplo artificial, digamos que tengo un método que debe funcionar sin distinción entre mayúsculas y minúsculas.
Sin final
:
public void doSomething(String input) {
input = input.toLowerCase();
// do a few things with input
}
Sencillo. Limpiar. Todos saben lo que está pasando.
Ahora con 'final', opción 1:
public void doSomething(final String input) {
final String lowercaseInput = input.toLowerCase();
// do a few things with lowercaseInput
}
Si bien la configuración de los parámetros final
impide que el codificador agregue código más abajo de pensar que está trabajando con el valor original, existe el mismo riesgo de que el código más abajo pueda usar en input
lugar de lowercaseInput
, lo que no debería y de lo que no puede protegerse, porque puede ' t sacarlo del alcance (o incluso asignar null
a input
si eso ayudaría de todos modos).
Con 'final', opción 2:
public void doSomething(final String input) {
// do a few things with input.toLowerCase()
}
Ahora acabamos de crear aún más ruido de código e introdujimos un golpe de rendimiento al tener que invocar toLowerCase()
n veces.
Con 'final', opción 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
}
Habla sobre el ruido de código. Este es un choque de trenes. Tenemos un nuevo método, un bloque de excepción requerido, porque otro código puede invocarlo incorrectamente. Más pruebas unitarias para cubrir la excepción. Todo para evitar una línea simple, y en mi humilde opinión preferible e inofensiva.
También está el problema de que los métodos no deberían ser tan largos que no se puedan asimilar visualmente y saber de un vistazo que se ha realizado una asignación a un parámetro.
Creo que es una buena práctica / estilo que si asigna un parámetro lo hace al principio del método, preferiblemente en primera línea o inmediatamente después de la verificación de entrada básica, reemplazándolo efectivamente por todo el método, lo que tiene un efecto consistente dentro del método método. Los lectores saben que cualquier tarea debe ser obvia (cerca de la declaración de firma) y en un lugar coherente, lo que mitiga en gran medida el problema que está tratando de evitar la adición final. En realidad, rara vez asigno parámetros, pero si lo hago, siempre lo hago en la parte superior de un método.
Tenga en cuenta también que en final
realidad no lo protege como puede parecer a primera vista:
public void foo(final Date date) {
date.setTime(0);
// code that uses date
}
final
no lo protege completamente a menos que el tipo de parámetro sea primitivo o inmutable.