create - java static inner class example
¿Por qué compilar una clase que contiene clases anidadas estáticas crea un nuevo archivo.class llamado "EnclosingClass $ 1"? (1)
Primero, eche un vistazo a la tabla de acceso de clase y la tabla de modificador de propiedades de las especificaciones de JVM.
Observe el indicador ACC_SYNTHETIC
cuya interpretación especifica que no está presente en el código fuente (en palabras más simples, se agregará cuando el compilador genere la clase).
Echemos un vistazo al EnclosingClass$1.class
(tenga en cuenta que EnclosingClass$1.class
solo la parte que importa).
javap -v EnclosingClass$1.class
producir el siguiente resultado
Classfile /C:/Users/jfrancoiss/Desktop/Nouveau dossier/EnclosingClass$1.class
Last modified 2015-03-31; size 190 bytes
MD5 checksum 5875440f1e7f5ea9a519d02fbec6dc8f
Compiled from "EnclosingClass.java"
class EnclosingClass$1
minor version: 0
major version: 52
flags: ACC_SUPER, ACC_SYNTHETIC
Observe que los indicadores de acceso de la clase contienen ACC_SYNTHETIC
.
El indicador ACC_SYNTHETIC indica que esta clase o interfaz fue generada por un compilador y no aparece en el código fuente.
Otra opción para asegurarse de que la clase generada sea sintética es compilar como
javac -XD-printflat EnclosingClass.java
que produciría
/*synthetic*/ class EnclosingClass$1 {
}
Genial, pero ¿por qué generar una clase sintética?
El tutorial de reflexión de Java puede ayudarnos a entender esto. Echa un vistazo a los comentarios en la clase SyntheticConstructor
public class SyntheticConstructor {
private SyntheticConstructor() {}
class Inner {
// Compiler will generate a synthetic constructor since
// SyntheticConstructor() is private.
Inner() { new SyntheticConstructor(); }
}
}
Así que de acuerdo con el comentario, la clase sintética EnclosingClass$1.class
se creó porque IBiLink
era privado.
Una vez más, el tutorial de reflexión de Java especifica en este punto.
Dado que el constructor de la clase interna hace referencia al constructor privado de la clase adjunta, el compilador debe generar un constructor privado de paquete.
En nuestro caso, no vemos explícitamente ninguna llamada de constructor, pero tenemos esta línea
public static class BiNode extends Sub.IBiLink { }
Vamos a intentar compilar este código y ver qué pasa.
class EnclosingClass
{
//public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}
No EnclosingClass$1.class
generada.
Más detalles notados al depurar
Cambio
private static class IBiLink
a
protected static class IBiLink
Observe que al compilar, no se crea EnclosingClass$1.class
.
¿Por qué la protección de la clase no generó una clase sintética?
Simplemente porque al proteger la clase, usted obtiene acceso implícitamente a cada una de las súper clases.
¿Por qué eclipse compiler no genera una clase sintética?
Eclipse lo utiliza como compilador incorporado, que puede configurarlo según el nivel de gravedad.
De forma predeterminada, el acceso a un miembro no accesible de un tipo envolvente está configurado para ignorar, como se puede ver en esta imagen.
Cámbielo, por ejemplo, a una advertencia y recibirá el siguiente mensaje.
lo que me permite creer que eclipse, aunque no crea otra clase, lo emulará para simular el miembro sintético.
Esta pregunta ya tiene una respuesta aquí:
En el siguiente código:
class EnclosingClass
{
public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}
Al compilar junto con otros archivos .class, también veo un archivo llamado "EnclosingClass $ 1.class". ¿Por qué se ha creado esto automáticamente? ¿Que esta pasando?