ProgramaciónDesarrollador Java

Hable sobre las características clave del trabajo con clases anónimas y anidadas en Java, así como sobre las trampas que conlleva su uso.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Clases anidadas — son clases definidas dentro de otra clase. Pueden ser:

  • Clases anidadas estáticas — no tienen acceso a miembros no estáticos de la clase externa sin una instancia.
  • Clases internas — clases anidadas no estáticas; tienen acceso a todos los miembros de la clase externa.
  • Clases anónimas — clases internas sin nombre, declaradas y creadas generalmente en el lugar de uso, a menudo al trabajar con interfaces/clases abstractas.

Ejemplo de una clase anónima:

Button b = new Button(); b.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // acción al hacer clic } });

Características:

  • Las clases anónimas solo pueden acceder a variables de la zona externa que sean final (effectively final).
  • En cada instancia de la clase interna, se almacena implícitamente una referencia a la instancia de la clase externa.
  • Dependiendo del tipo (static/inner), pueden surgir fugas de memoria o dependencias inesperadas.

Pregunta trampa.

¿Puede una clase interna (non-static inner) contener métodos o variables estáticas?

Respuesta: No, no puede, excepto constantes (static final). Solo la clase anidada estática (static nested class) puede tener miembros estáticos.

Ejemplo (error):

class Outer { class Inner { static int x = 10; // ¡Error de compilación! } }

Correctamente sería así:

class Outer { static class StaticNested { static int x = 10; // OK } }

Ejemplos de errores reales debido a la falta de conocimiento de las sutilezas del tema.


Historia

En una aplicación de Android se utilizó una clase interna como manejador de eventos. El manejador se almacenaba en un campo estático y mantenía una referencia implícita a la Activity, lo que causaba una fuga de memoria al destruirla, y la aplicación empezaba a "filtrarse", hasta llegar a OutOfMemoryError.


Historia

En uno de los microservicios se utilizaron clases anónimas que hacían referencia a variables externas iteradoras. Después de la refactorización, las variables dejaron de ser effectively final, y el código dejó de compilarse — los desarrolladores buscaron durante mucho tiempo la causa, hasta que recordaron esta limitación.


Historia

En una biblioteca se utilizaron variables estáticas dentro de una clase interna, pensando que era una práctica común. En nuevas versiones de JDK, el proyecto dejó de compilarse, ya que el estándar comenzó a seguir más estrictamente las limitaciones. Se necesitó una reestructuración urgente de la arquitectura.