method inner example create classes java javac nested-class .class-file

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.

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?