Qué diferencia hay final
entre el siguiente código. ¿Hay alguna ventaja en declarar los argumentos como final
.
public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){
return ....
}
public String changeTimezone(final Timestamp stamp, final Timezone fTz,
final Timezone toTz){
return ....
}
Respuestas:
Como un parámetro de método formal es una variable local, puede acceder a ellos desde clases anónimas internas solo si están declaradas como finales.
Esto le evita declarar otra variable final local en el cuerpo del método:
void m(final int param) { new Thread(new Runnable() { public void run() { System.err.println(param); } }).start(); }
fuente
Extracto de La última palabra sobre la palabra clave final
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... }
fuente
La final le impide asignar un nuevo valor a la variable, y esto puede ser útil para detectar errores tipográficos. Estilísticamente, es posible que desee mantener los parámetros recibidos sin cambios y asignarlos solo a variables locales, por lo que final ayudaría a hacer cumplir ese estilo.
Debo admitir que rara vez recuerdo usar final para los parámetros, tal vez debería.
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; }
fuente
No hace mucha diferencia. Simplemente significa que no puedes escribir:
stamp = null; fTz = new ...;
pero aún puedes escribir:
Es principalmente una pista para el programador de mantenimiento que le sigue de que no va a asignar un nuevo valor al parámetro en algún lugar en el medio de su método donde no es obvio y, por lo tanto, podría causar confusión.
fuente
La palabra clave final cuando se usa para parámetros / variables en Java marca la referencia como final. En caso de pasar un objeto a otro método, el sistema crea una copia de la variable de referencia y la pasa al método. Al marcar las nuevas referencias como definitivas, las protege de la reasignación. A veces se considera una buena práctica de codificación.
fuente
Para el cuerpo de este método, la
final
palabra clave evitará que las referencias de los argumentos se reasignen accidentalmente dando un error de compilación en esos casos (la mayoría de los IDE se quejarán de inmediato). Algunos pueden argumentar que el usofinal
en general siempre que sea posible acelerará las cosas, pero ese no es el caso en las JVM recientes.fuente
Se enumeran dos ventajas que veo:
1 Marcar el argumento del método como final evita la reasignación del argumento dentro del método
De tu ejemplo
public String changeTimezone(final Timestamp stamp, final Timezone fTz, final Timezone toTz){ // THIS WILL CAUSE COMPILATION ERROR as fTz is marked as final argument fTz = Calendar.getInstance().getTimeZone(); return .. }
En un método complicado, marcar los argumentos como finales ayudará en la interpretación accidental de estos argumentos como variables locales de métodos y reasignarlos como compilador marcará estos casos como se muestra en el ejemplo.
2 Pasando el argumento a una clase interna anónima
Como un parámetro de método formal es una variable local, puede acceder a ellos desde clases anónimas internas solo si están declaradas como finales.
fuente
- En el pasado (antes de Java 8 :-))
Explique el uso de la accesibilidad afectada por la palabra clave "final" de la variable de método para clases internas anónimas.
- En lenguaje de lenguaje moderno (Java 8+) no hay necesidad de tal uso:
Java introdujo variables "efectivamente finales". Las variables locales y los parámetros del método se asumen como finales si el código no implica un cambio de valor de la variable. Entonces, si ve dicha palabra clave en Java8 +, puede asumir que no es necesaria. La introducción de "efectivamente final" nos hace escribir menos código cuando usamos lambdas.
fuente
Es solo una construcción en Java para ayudarlo a definir un contrato y cumplirlo. Una discusión similar aquí: http://c2.com/cgi/wiki?JavaFinalConsideredEvil
Por cierto, (como dice el twiki), marcar args como final es generalmente redundante si está siguiendo buenos principios de programación y ya ha reasignado / redefinido la referencia de argumento entrante.
En el peor de los casos, si redefine la referencia de args, no afectará el valor real pasado a la función, ya que solo se pasó una referencia.
fuente
Estoy hablando de marcar variables y campos como finales en general, no solo se aplica a los argumentos del método. (Marcar métodos / clases finales es algo completamente diferente).
Es un favor para los lectores / futuros mantenedores de su código. Junto con un nombre sensato de la variable, es útil y tranquilizador para el lector de su código ver / comprender lo que representan las variables en cuestión, y es tranquilizador para el lector que siempre que vea la variable en el mismo ámbito, el significado permanece lo mismo, por lo que no tiene que rascarse la cabeza para descubrir siempre qué significa una variable en cada contexto. Hemos visto demasiados abusos de "reutilización" de variables, lo que hace que incluso un pequeño fragmento de código sea difícil de entender.
fuente
La palabra clave final le impide asignar un nuevo valor al parámetro. Me gustaría explicar esto con un ejemplo simple.
Supongamos que tenemos un método
En el caso anterior, si se asigna un nuevo valor a "dateOfBirth" en el método2, esto daría como resultado una salida incorrecta del método3. Como el valor que se pasa al método3 no es el que era antes de pasar al método2. Entonces, para evitar esta palabra clave final, se usa para parámetros.
Y esta es también una de las mejores prácticas de codificación de Java.
fuente