Modificador final de Java

Me dijeron eso, no entendí los efectos de la final . ¿Cuáles son los efectos de final palabra clave final ?

Aquí hay una breve descripción de lo que pienso, lo sé:

Modificador final de Java (también conocido como relación de agregación)

variables primitivas : se pueden establecer solo una vez. (ganancia de memoria y rendimiento)
variables de objetos : puede ser modificado, el final se aplica a la referencia del objeto.
campos : se puede establecer solo una vez.
métodos : no pueden ser anulados, ocultos.
clases : no se puede extender.
recolección de basura : obligará a Java generational recolección de basura marca-barrido a doble barrido.

Can y Cant

  • Puede hacer que el clon falle (esto es bueno y malo)
  • Puede hacer primitivos inmutables aka const
  • Puede hacer que el blanco sea inmutable: inicializado en la creación, también conocido como readonly
  • Puede hacer objetos poco profundos inmutables
  • Puede hacer el scope / la visibilidad inmutable
  • Puede hacer que la sobrecarga de invocación de método sea más pequeña (porque no necesita tabla virtual)
  • Puede hacer que los argumentos del método se usen como finales (incluso si no lo son)
  • Puede hacer que los objetos sean enhebrables (si el objeto se define como final, no hará que los argumentos del método sean definitivos)
  • Puede hacer pruebas simuladas (no es que pueda hacer algo al respecto; puede decir que los errores están destinados)
  • No puedo hacer amigos (mutables con otros amigos e inmutables para descansar)
  • No se puede hacer mutable que se cambie para que sea inmutable más tarde (pero puede con un patrón de fábrica como solución)
  • No se puede hacer que los elementos de la matriz sean inmutables, alias, profundamente inmutables
  • No se pueden crear nuevas instancias de objeto (esto es bueno y malo)
  • No se puede hacer que la serialización funcione

No hay alternativas al final , pero hay wrapper + private y enums.

Respondiendo cada uno de tus puntos a la vez:

variables primitivas: se pueden establecer solo una vez. (ganancia de memoria y rendimiento)

Sí, pero no hay ganancia de memoria ni ganancia de rendimiento. (Su supuesta ganancia de rendimiento proviene de establecer solo una vez … no desde el final ).

variables de objetos: puede ser modificado, el final se aplica a la referencia del objeto.

Sí. (Sin embargo, esta descripción omite el hecho de que esto es totalmente coherente con la forma en que el rest del lenguaje Java trata con la dualidad objeto / referencia. Por ejemplo, cuando los objetos se pasan como parámetros y se devuelven como resultados).

campos: se puede establecer solo una vez.

La respuesta real es: lo mismo que para las variables.

métodos: no pueden ser anulados, ocultos.

Sí. Pero también tenga en cuenta que lo que está sucediendo aquí es que la palabra clave final se está utilizando en un contexto sintáctico diferente para significar algo diferente a la final para un campo / variable.

clases: no se puede extender.

Sí. Pero también vea la nota de arriba.

recolección de basura: obligará a Java generational recolección de basura marca-barrido a doble barrido.

Esto no tiene sentido. La palabra clave final no tiene relevancia alguna para la recolección de elementos no utilizados. Puede ser confuso final con finalización … no están relacionados.

Pero incluso los finalizadores no fuerzan un barrido adicional. Lo que ocurre es que un objeto que necesita finalización se establece en un lado hasta que finaliza el GC principal. El GC luego ejecuta el método de finalización en el objeto y establece su indicador … y continúa. La próxima vez que se ejecuta el GC, el objeto se trata como un objeto normal:

  • si es accesible, está marcado y copiado
  • si no es alcanzable, no está marcado.

(Su caracterización – “Generación de recolección de basura generacional de Java marcaje” está distorsionada. Un recolector de basura puede ser “marca de barrido” O “generacional” (una subclase de “copia”). No puede ser ambas. Java normalmente usa la recostackción generacional, y solo regresa a marcar barridos en emergencias, es decir, cuando se está quedando sin espacio o cuando un colector de baja pausa no puede mantener el ritmo).

Puede hacer que el clon falle (esto es bueno y malo)

No lo creo.

Puede hacer primitivos inmutables aka const

Sí.

Puede hacer que el blanco sea inmutable: inicializado en la creación, también conocido como readonly

Sí … aunque nunca escuché el término “inmutables en blanco” antes.

Puede hacer objetos poco profundos inmutables

La mutabilidad del objeto se trata de si el estado observable puede cambiar. Como tal, declarar atributos final puede o no hacer que el objeto se comporte como inmutable. Además, la noción de “superficialmente inmutable” no está bien definida, sobre todo porque la noción de lo que es “superficial” no se puede mapear sin un conocimiento profundo de la semántica de clase.

(Para ser claros, la mutabilidad de variables / campos es un concepto bien definido en el contexto del JLS. Es solo el concepto de mutabilidad de los objetos el que no está definido desde la perspectiva del JLS).

Puede hacer el scope / la visibilidad inmutable

Error de terminología La mutación es sobre el estado del objeto. La visibilidad y el scope no lo son.

Puede hacer que la sobrecarga de invocación de método sea más pequeña (porque no necesita una tabla virtual)

En la práctica, esto es irrelevante. Un comstackdor JIT moderno también hace esta optimización para métodos no finales, si no son reemplazados por ninguna clase que la aplicación realmente utiliza. (Cosas inteligentes suceden …)

Puede hacer que los argumentos del método se usen como finales (incluso si no lo son)

¿Huh? No puedo analizar esta oración.

Puede hacer que los objetos sean seguros

En ciertas situaciones, sí.

(si el objeto se define como final, no hará que los argumentos del método sean definitivos)

Sí, si quieres decir si la clase es final. Los objetos no son finales.

Puede hacer pruebas simuladas (no es que pueda hacer algo al respecto; puede decir que los errores están destinados)

No analiza

No puedo hacer amigos (mutables con otros amigos e inmutables para descansar)

Java no tiene “amigos”.

No se puede hacer mutable que se cambie para que sea inmutable más tarde (pero puede con un patrón de fábrica como solución)

Sí al primero, un campo final no se puede cambiar de mutable a inmutable.

No está claro a qué te refieres con la segunda parte. Es cierto que puede usar un patrón de fábrica (o constructor) para construir objetos inmutables. Sin embargo, si utiliza final para los campos de objetos en ningún punto, el objeto será mutable.

Alternativamente, puede implementar objetos inmutables que usan campos no finales para representar el estado inmutable, y puede diseñar la API para que pueda “activar un interruptor” para hacer que un objeto previamente mutable sea inmutable desde ahora en adelante. Pero si toma este enfoque, debe ser mucho más cuidadoso con la sincronización … si sus objetos necesitan ser seguros para la ejecución de subprocesos.

No se puede hacer que los elementos de la matriz sean inmutables, alias, profundamente inmutables

Sí, pero su terminología está rota; ver el comentario anterior sobre “mutabilidad superficial”.

No se pueden crear nuevas instancias de objeto (esto es bueno y malo)

No. No hay nada que te impida hacer una nueva instancia de un objeto con campos finales o una clase final o métodos finales.

No se puede hacer que la serialización funcione

No. La serialización funciona. (Por supuesto, la deserialización de los campos final utilizando un método readObject personalizado presenta problemas … aunque puede solucionarlos mediante el uso de hacks de reflexión).

No hay alternativas al final,

Correcto.

pero hay envoltorio + privado

Sí, módulo que (estrictamente hablando) un getter no sincronizado para un campo no final puede no ser seguro para subprocesos … incluso si se inicializa durante la construcción del objeto y luego nunca cambia !

y enums.

Resuelve un problema diferente. Y las enums pueden ser mutables.

La palabra clave final se usa generalmente para preservar la inmutabilidad. Utilizar las clases o los métodos finales es evitar que se rompan los vínculos entre los métodos. Por ejemplo, supongamos que la implementación de algún método de la clase X supone que el método M se comportará de cierta manera. Declarar X o M como final impedirá que las clases derivadas redefinan M de tal manera que X se comporte incorrectamente.