usar - public static java
¿Es posible hacer que las clases internas anónimas en Java estén estáticas? (6)
Creo que hay un poco de confusión en la nomenclatura aquí, que sin duda es demasiado tonto y confuso.
Como sea que los llame, estos patrones (y algunas variaciones con diferente visibilidad) son todos posibles, normales, legales de Java:
public class MyClass {
class MyClassInside {
}
}
public class MyClass {
public static class MyClassInside {
}
}
public class MyClass {
public void method() {
JComponent jc = new JComponent() {
...
}
}
}
public class MyClass {
public static void myStaticMethod() {
JComponent jc = new JComponent() {
...
}
}
}
Se atienden en la especificación del idioma (si realmente está molesto, consulte la sección 15.9.5.1 para conocer el método estático).
Pero esta cita es simplemente incorrecta :
javac.exe permitirá clases anónimas dentro de código de inicio estático y métodos estáticos, aunque la especificación de idioma indica que las clases anónimas nunca son estáticas.
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", etc.). Realmente, nadie va a eliminar de repente esta funcionalidad en la próxima versión de Java. ¡Honestamente!
En Java, las clases anidadas pueden ser static
o no. Si son static
, no contienen una referencia al puntero de la instancia que los contiene (tampoco se les llama clases internas, se les llama clases anidadas).
Olvidarse de 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 lo resuelve automáticamente (que podría, porque no puede haber subclases)?
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());
}
}
En la nota de hacer una clase interna anónima estática llamándolos dentro de un método estático.
Esto en realidad no elimina la referencia. Puede probar esto tratando de serializar la clase anónima y no hacer que la clase adjunta sea serializable.
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í .
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.
Existen algunas diferencias técnicas entre clases internas en contextos estáticos y clases anidadas estáticas. Si estás interesado, lee el JLS 3rd Ed.
No, no puedes, y no, el compilador no puede resolverlo. Esta es la razón por la cual FindBugs siempre sugiere cambiar las clases internas anónimas a clases anidadas static
con nombre si no usan su 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 método main
), la clase anónima es, de hecho, static
. Pero el JLS disagrees :
Una clase anónima nunca es
abstract
(§8.1.1.1). Una clase anónima es siempre una clase interna (§8.1.3); nunca esstatic
(§8.1.1, §8.5.1). Una clase anónima siempre es implícitamentefinal
(§8.1.1.2).
El Glosario Java de Roedy Green dice que el hecho de que las clases anónimas estén permitidas en un contexto estático depende de la implementación:
Si quieres desconcertar a quienes mantienen tu código, los
javac.exe
han descubierto quejavac.exe
permitirá las clases anónimas dentro del código de iniciostatic
ystatic
métodosstatic
, a pesar de que la especificación del lenguaje indica que las clases anónimas nunca sonstatic
. Estas clases anónimas, por supuesto, no tienen acceso a los campos de instancia del objeto. No recomiendo hacer esto La función se puede extraer en cualquier momento.
Edición 2: El JLS en realidad cubre contextos estáticos más explícitamente en §15.9.2 :
Deje que C sea la clase que se crea una instancia, y permítame ser la instancia que se está creando. Si C es una clase interna, entonces puedo tener una instancia que encierre inmediatamente. La instancia de I inmediatamente adjunta (§8.1.3) se determina de la siguiente manera.
- Si C es una clase anónima, entonces:
- Si la expresión de creación de instancia de clase se produce en un contexto estático (§8.1.3), entonces no tengo ninguna instancia que lo encierre inmediatamente.
- De lo contrario, la instancia de i que lo rodea inmediatamente es
this
.
Por lo tanto, una clase anónima en un contexto estático es más o menos equivalente a una clase anidada static
, ya que no mantiene una referencia a la clase adjunta, aunque técnicamente no es una clase static
.
las clases internas anónimas nunca son estáticas (no pueden declarar métodos estáticos o campos estáticos no finales), pero si están definidas en un contexto estático (método estático o campo estático) se comportan como estáticas en el sentido de que no pueden acceder a miembros no estáticos (es decir, instancia) de la clase adjunta (como todo lo demás desde un contexto estático)