He encontrado un par de referencias ( por ejemplo ) que sugieren usarfinal
tanto como sea posible y me pregunto qué tan importante es eso. Esto es principalmente en el contexto de parámetros de métodos y variables locales, no en métodos finales o clases. Para las constantes, tiene sentido obvio.
Por un lado, el compilador puede hacer algunas optimizaciones y aclara la intención del programador. Por otro lado, agrega verbosidad y las optimizaciones pueden ser triviales.
¿Es algo que debería hacer un esfuerzo por recordar?
Respuestas:
Obsesionarse con:
Considere pero use juiciosamente:
Ignorar a menos que se sienta anal:
Parámetros del método y variables locales: RARAMENTE hago esto en gran medida porque soy flojo y me parece que satura el código. Admitiré completamente que marcar parámetros y variables locales que no voy a modificar es "más correcto". Desearía que fuera el valor predeterminado. Pero no lo es y encuentro que el código es más difícil de entender con finales por todas partes. Si estoy en el código de otra persona, no voy a extraerlo, pero si escribo un código nuevo no lo pondré. Una excepción es el caso en el que tiene que marcar algo final para que pueda acceder desde dentro de una clase interna anónima.
Editar: tenga en cuenta que un caso de uso donde las variables locales finales son realmente muy útiles como lo menciona @ adam-gent es cuando el valor se asigna a la var en las
if
/else
ramas.fuente
final
por defecto. Sin embargo, es posible que no note los beneficios a menos que utilice un Java IDE verdaderamente moderno (es decir, IDEA).final
clases / métodos. Por ejemplo, si un método final declara lanzar una excepción marcada pero nunca la arroja, IDEA le dirá eso, y usted puede eliminar la excepción de lathrows
cláusula. A veces, también puede encontrar métodos completos que no se utilizan, lo que es detectable cuando no se pueden anular.No, si está utilizando Eclipse, porque puede configurar una Acción de guardado para agregar automáticamente estos modificadores finales . Entonces obtienes los beneficios por menos esfuerzo.
fuente
Los beneficios en tiempo de desarrollo de "final" son al menos tan significativos como los beneficios en tiempo de ejecución. Le dice a los futuros editores del código algo sobre sus intenciones.
Marcar una clase como "final" indica que no ha hecho un esfuerzo durante el diseño o la implementación de la clase para manejar la extensión con gracia. Si los lectores pueden hacer cambios en la clase y desean eliminar el modificador "final", pueden hacerlo bajo su propio riesgo. Depende de ellos asegurarse de que la clase manejará bien la extensión.
Marcar una variable "final" (y asignarla en el constructor) es útil con la inyección de dependencia. Indica la naturaleza "colaboradora" de la variable.
Marcar un método "final" es útil en clases abstractas. Delinea claramente dónde están los puntos de extensión.
fuente
Uso
final
todo el tiempo para hacer que Java esté más basado en expresiones. Ver las condiciones de Java (if,else,switch
) no están basadas en expresiones, lo que siempre he odiado, especialmente si está acostumbrado a la programación funcional (es decir, ML, Scala o Lisp).Por lo tanto, debe intentar usar siempre (en mi humilde opinión) las variables finales cuando use condiciones.
Dejame darte un ejemplo:
Ahora si agrega otra
case
instrucción y no la configura,name
el compilador fallará. El compilador también fallará si no interrumpe en todos los casos (si establece la variable). Esto le permite hacer que Java sea muy similar a la de Lisplet
expresiones y hace que su código no tenga una sangría masiva (debido a las variables de alcance léxico).Y como señaló @Recurse (pero aparentemente -1 yo), puede hacer lo anterior sin hacer
String name
final
para obtener el error del compilador (que nunca dije que no podría), pero podría hacer que el error del compilador desaparezca fácilmente configurando el nombre después del cambio declaración que descarta la expresión semántica o, lo que es peor, olvidandobreak
que no puede causar un error (a pesar de lo que dice @Recurse) sin usarfinal
:Debido al nombre de configuración del error (además de olvidar a
break
qué otro error) ahora puedo hacer esto accidentalmente:La variable final obliga a una sola evaluación de qué nombre debe ser. De forma similar a cómo una función que tiene un valor de retorno siempre debe devolver un valor (sin tener en cuenta las excepciones), el bloque de cambio de nombre tendrá que resolver el nombre y, por lo tanto, unido a ese bloque de cambio que facilita la refactorización de fragmentos de código (es decir, refactorización de Eclipe: método de extracción) .
Lo anterior en OCaml:
El
match ... with ...
evalúa como una función, es decir, expresión. Observe cómo se ve nuestra declaración de cambio.Aquí hay un ejemplo en Scheme (Racket or Chicken):
fuente
else if (...)
aif(...)
y, por lo tanto, restablece la variable. Le mostré que nunca habría sucedido con una variable final. Básicamentefinal
te obliga a asignar la variable una vez y solo una vez ... entonces: PHe encontrado parámetros y métodos locales de marcado, ya que
final
es útil como ayuda de refactorización cuando el método en cuestión es un desastre incomprensible de varias páginas. Espolvorearfinal
generosamente, vea qué errores "no se pueden asignar a la variable final" el compilador (o su IDE) arroja, y puede descubrir por qué la variable llamada "datos" termina siendo nula a pesar de que varios comentarios (desactualizados) juran que pueden No sucedaLuego puede corregir algunos de los errores reemplazando las variables reutilizadas con nuevas variables declaradas más cercanas al punto de uso. Luego descubres que puedes envolver partes enteras del método en llaves de alcance, y de repente estás presionando una tecla IDE fuera del "Método de extracción" y tu monstruo se vuelve más comprensible.
Si su método aún no es un desastre imposible de mantener, supongo que puede ser útil hacer que las cosas sean definitivas para disuadir a las personas de convertirlo en dicho desastre; pero si es un método corto (ver: no imposible de mantener) entonces corre el riesgo de agregar mucha verbosidad. En particular, las firmas de funciones de Java son lo suficientemente difíciles como para caber en 80 caracteres, ¡sin agregar seis más por argumento!
fuente
final
antes de cada parámetro.Bueno, todo depende de tu estilo ... si te GUSTA ver la final cuando no vas a modificar la variable, entonces úsala. Si NO TE GUSTA verlo ... entonces déjalo afuera.
Personalmente, me gusta la menor verbosidad posible, por lo que tiendo a evitar el uso de palabras clave adicionales que no son realmente necesarias.
Sin embargo, prefiero los lenguajes dinámicos, por lo que probablemente no sea una sorpresa que me guste evitar la verbosidad.
Por lo tanto, yo diría que solo elija la dirección hacia la que se inclina e ir con ella (en cualquier caso, trate de ser coherente).
Como nota al margen, he trabajado en proyectos que usan y no usan ese patrón, y no he visto ninguna diferencia en la cantidad de errores o errores ... No creo que sea un patrón que pueda mejore su conteo de errores o cualquier cosa, pero nuevamente es estilo, y si le gusta expresar la intención de que no lo modificará, continúe y utilícelo.
fuente
Es útil en los parámetros para evitar cambiar el valor del parámetro por accidente e introducir un error sutil. Solía ignorar esta recomendación, pero después de pasar unas 4 horas. en un método horrible (con cientos de líneas de código y múltiples fors, ifs anidados y todo tipo de malas prácticas), le recomendaría que lo haga.
Por supuesto, en un mundo perfecto esto no sucedería, pero ... bueno ... a veces tienes que admitir el código de otros. :(
fuente
Si está escribiendo una aplicación en la que alguien tendrá que leer el código después de, por ejemplo, 1 año, entonces sí, use la variable final en que no debe modificarse todo el tiempo. Al hacer esto, su código será más "autodocumentado" y también reducirá la posibilidad de que otros desarrolladores hagan cosas tontas como usar una constante local como una variable temporal local.
Si está escribiendo un código desechable, entonces, no, no se moleste en identificar todas las constantes y hacerlas finales.
fuente
Usaré final tanto como pueda. Si lo hace, se marcará si cambia involuntariamente el campo. También establecí los parámetros del Método en final. Al hacerlo, detecté varios errores del código que asumí cuando intentan 'establecer' un parámetro olvidando los pases de Java por valor.
fuente
No queda claro a partir de la pregunta si esto es obvio, pero hacer que un parámetro del método sea final solo afecta al cuerpo del método. No NO transmitir cualquier información interesante acerca de las intenciones del método para el invocador. El objeto que se pasa aún puede ser mutado dentro del método (las finales no son constantes), y el alcance de la variable está dentro del método.
Para responder a su pregunta precisa, no me molestaría en hacer una instancia o variable local (incluidos los parámetros del método) final a menos que el código lo requiera (por ejemplo, la variable se hace referencia desde una clase interna), o para aclarar alguna lógica realmente complicada.
Por ejemplo, las variables, las haré finales si son lógicamente constantes.
fuente
Hay muchos usos para la variable
final
. Aquí hay algunosConstantes finales
Esto puede usarse luego para otras partes de sus códigos, o acceder a otras clases, de esa manera si alguna vez cambiara el valor, no tendría que cambiarlos uno por uno.
Variables finales
En esta clase, construye una variable final con ámbito que agrega un prefijo al parámetro environmentKey. En este caso, la variable final es final solo dentro del alcance de ejecución, que es diferente en cada ejecución del método. Cada vez que se ingresa el método, se reconstruye el final. Tan pronto como se construye, no se puede cambiar durante el alcance de la ejecución del método. Esto le permite corregir una variable en un método durante la duración del método. vea abajo:
Constantes finales
Estos son especialmente útiles cuando tiene líneas de códigos realmente largas, y generará un error del compilador para que no se encuentre con un error lógico / comercial cuando alguien cambia accidentalmente variables que no deberían cambiarse.
Colecciones finales
Caso diferente cuando hablamos de colecciones, debe establecerlas como no modificables.
de lo contrario, si no lo configura como no modificable:
Las clases finales y los métodos finales no pueden ampliarse ni sobrescribirse, respectivamente.
EDITAR: PARA ABORDAR EL PROBLEMA DE CLASE FINAL SOBRE LA ENCAPSULACIÓN:
Hay dos formas de hacer una clase final. El primero es usar la palabra clave final en la declaración de clase:
La segunda forma de hacer que una clase sea final es declarar a todos sus constructores como privados:
Marcarlo como final te ahorra el problema si descubres que es una final real, para demostrar que miras esta clase de Prueba. parece público a primera vista.
Desafortunadamente, dado que el único constructor de la clase es privado, es imposible extender esta clase. En el caso de la clase Test, no hay razón para que la clase sea final. La clase Test es un buen ejemplo de cómo las clases finales implícitas pueden causar problemas.
Por lo tanto, debe marcarlo como final cuando implícitamente haga una clase final haciendo que su constructor sea privado.
fuente
Como mencionas, es una compensación, pero prefiero el uso explícito de algo sobre el uso implícito. Esto ayudará a eliminar cierta ambigüedad para los futuros mantenedores de código, incluso si es solo usted.
fuente
Si tiene clases internas (anónimas) y el método necesita acceder a la variable del método contenedor, debe tener esa variable como final.
Aparte de eso, lo que has dicho es correcto.
fuente
Use la
final
palabra clave para una variable si está haciendo esa variable comoimmutable
Al declarar la variable como final, ayuda a los desarrolladores a descartar posibles problemas de modificación de variables en un entorno altamente multiproceso.
Con el lanzamiento de Java 8, tenemos un concepto más llamado "
effectively final variable
". Una variable no final puede desplazarse como variable final.Las variables locales a las que se hace referencia desde una expresión lambda deben ser finales o efectivamente finales
Hasta Java 7, no puede usar una variable local no final dentro de una clase anónima, pero desde Java 8 puede
Echa un vistazo a este artículo
fuente
En primer lugar, la palabra clave final se usa para hacer una variable constante. Constante significa que no cambia. Por ejemplo:
Declararía la variable final porque un centímetro por pulgada no cambia.
Si intenta anular un valor final, la variable es lo que se declaró primero. Por ejemplo:
Hay un error de compilación que es algo así como:
Si su variable no se puede declarar final o si no desea declararla final, intente esto:
Esto imprimirá:
fuente