ProgramaciónDesarrollador Java

¿Cómo funciona el mecanismo final en Java — para variables, métodos y clases, y qué efectos inesperados puede causar un uso incorrecto de este modificador?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

final en Java se utiliza para:

  • Variables — se vuelve inmutable después de la inicialización;
  • Métodos — no se puede sobrescribir en los heredados;
  • Clases — no se pueden crear heredados.

Características y matices:

  • La variable final debe ser inicializada al declararse o en el constructor;
  • La referencia final no permite cambiar la referencia, pero se puede cambiar el objeto al que apunta (¡si no es inmutable!);
  • No se puede heredar de una clase final (por ejemplo, String, Math);
  • No se puede sobrescribir un método final, incluso si la clase es heredada.
final class A {} // no se puede hacer class B extends A class Parent { final void foo() { } } class Child extends Parent { // void foo() {} // error: no se puede retornar foo } final int COUNT = 10;

Pregunta capciosa.

¿Se puede cambiar el estado del objeto al que apunta una variable final?

Respuesta: Sí, si no es un objeto inmutable. Por ejemplo:

final List<String> names = new ArrayList<>(); names.add("Vasya"); // Esto es permitido — se cambia el objeto por la referencia, pero no la referencia misma names = new ArrayList<>(); // Error de compilación

Ejemplos de errores reales debido al desconocimiento de los matices del tema.


Historia

En el sistema de registro, el único final Logger se pasaba por todo el código, creyendo que el objeto estaba completamente protegido — pero cambiaban la configuración a través de un método público, rompiendo la configuración globalmente.

Historia

En la clase utilitaria se hicieron campos finales del tipo List, y luego intentaron devolverlos hacia afuera para uso general. El código externo modificaba el contenido de la lista a través de la referencia recibida — final no protege de esto.

Historia

Surgió la tarea de ampliar la API externa, construida sobre clases finales. Debido a ellas, resultó imposible hacer la extensión, tuvieron que duplicar la lógica y mantener dos ramas independientes del producto, lo que complicó las migraciones.