En Java, las clases anidadas pueden ser static
o no. Si lo son static
, no contienen una referencia al puntero de la instancia que lo contiene (ya no se llaman clases internas, se llaman clases anidadas).
Olvidar hacer una clase anidada static
cuando no necesita esa referencia puede ocasionar problemas con la recolección de basura o el análisis de escape.
¿Es posible hacer una clase interna anónima static
también? ¿O el compilador resuelve esto automáticamente (que podría, porque no puede haber ninguna subclase)?
Por ejemplo, si hago un comparador anónimo, casi nunca necesito la referencia al exterior:
Collections.sort(list, new Comparator<String>(){
int compare(String a, String b){
return a.toUpperCase().compareTo(b.toUpperCase());
}
}
java
syntax
inner-classes
Thilo
fuente
fuente
Collections.sort(list, String.CASE_INSENSITIVE_ORDER)
funciona desde Java 2, lea, ya que existe la API de colección ...Respuestas:
No, no puedes, y no, el compilador no puede resolverlo. Es por eso que FindBugs siempre sugiere cambiar las clases internas anónimas a clases
static
anidadas con nombre si no usan suthis
referencia implícita .Editar: Tom Hawtin - tackline dice que si la clase anónima se crea en un contexto estático (por ejemplo, en el
main
método), la clase anónima sí lo esstatic
. Pero el JLS no está de acuerdo :El Glosario de Java de Roedy Green dice que el hecho de que se permitan clases anónimas en un contexto estático depende de la implementación:
Edición 2: El JLS en realidad cubre contextos estáticos más explícitamente en §15.9.2 :
Entonces, una clase anónima en un contexto estático es más o menos equivalente a una
static
clase anidada en el sentido de que no mantiene una referencia a la clase adjunta, aunque técnicamente no es unastatic
clase.fuente
true
usando javac (sun-jdk-1.7.0_10) yfalse
usando el compilador Eclipse.Mas o menos. Una clase interna anónima creada en un método estático obviamente será efectivamente estática porque no hay una fuente para esto externo.
Existen algunas diferencias técnicas entre las clases internas en contextos estáticos y las clases anidadas estáticas. Si estás interesado, lee el JLS 3rd Ed.
fuente
Creo que hay un poco de confusión en la nomenclatura aquí, que sin duda es demasiado tonta y confusa.
Como sea que los llame, estos patrones (y algunas variaciones con diferente visibilidad) son todos Java posibles, normales y legales:
Están atendidos en la especificación del idioma (si está realmente molesto, consulte la sección 15.9.5.1 para conocer el que está dentro del método estático).
Pero esta cita es simplemente errónea :
Creo que el autor citado confunde la palabra clave estática con el contexto estático . (Es cierto que el JLS también es un poco confuso a este respecto).
Honestamente, todos los patrones anteriores están bien (como los llames "anidados", "internos", "anónimos", lo que sea ...). Realmente, nadie va a eliminar repentinamente esta funcionalidad en la próxima versión de Java. ¡Honestamente!
fuente
new
yJComponent
en su tercer ejemplo.Las clases internas no pueden ser estáticas: una clase anidada estática no es una clase interna. El tutorial de Java habla sobre esto aquí .
fuente
las clases internas anónimas nunca son estáticas (no pueden declarar métodos estáticos o campos estáticos no finales), pero si se definen en un contexto estático (método estático o campo estático) se comportan como estáticos en el sentido de que no pueden Acceder a miembros no estáticos (es decir, instancia) de la clase que los encierra (como todo lo demás desde un contexto estático)
fuente
En la nota de hacer una clase interna anónima estática llamándolas dentro de un método estático.
Esto en realidad no elimina la referencia. Puede probar esto intentando serializar la clase anónima y no haciendo serializable la clase adjunta.
fuente