2010-01-27 22 views
7

En Java, en la compilación obtenemos un archivo .class para cada clase (incluidas las clases y las interfaces anidadas) definidas en el archivo fuente.

¿Cuál es el motivo de esta generación múltiple de archivos .class?
¿Es para simplificar la reutilizabilidad de la clase?
¿Por qué no generar una .class para un archivo .java?¿Por qué Java genera varios archivos .class en la compilación?

+0

El hecho de que 1 clase Java esté almacenada en exactamente 1 archivo .class y ese archivo .class contenga exactamente 1 clase (tipo, de hecho, también puede ser una interfaz, tipo de anotación o enum) simplifica el manejo y la carga de ambas Clases y archivos .class. –

Respuesta

7

En respuesta a la pregunta retórica de @ Jon Skeet:

Otra clase a continuación, se refiere a bar, por lo que la JVM necesita el código para ello ... ¿Cómo sugieren que encuentra el archivo?

Suponga (hipotéticamente) que el formato del archivo de clases de Java representa las clases anidadas/internas incrustándolas en el archivo de clase para la clase más externa. El nombre binario para la barra es "Lsome/pkg/Foo$Bar;". El cargador de clase podría dividir el nombre en el carácter "$", usar la primera parte para localizar el archivo de clase para Foo y luego navegar a la representación de clase de Barra incorporada.

Creo que la verdadera razón por la que las clases internas/anidadas tienen archivos de clase separados es histórica. IIRC, Java 1.0 no admitía clases anidadas o internas, y por lo tanto, los formatos de archivo de clase correspondientes no necesitaban tratar con ellos. Cuando se creó Java 1.1 (admitiendo clases internas/anidadas), Sun quería que el formato de archivo de clase fuera compatible con los archivos de clase producidos por el compilador de Java 1.0. Por lo tanto, eligieron implementar clases internas/anidadas como archivos de clase separados, utilizando el carácter reservado "$" en el nombre de clase binario.

Una segunda posible razón es que el formato plano simplifica la carga de clase en comparación con un formato embebido hipotético.

Y, por último, no existía (y aún no existe) una razón de peso para que NO utilicen un formato de archivo plano. Puede crear pequeños arañazos en la cabeza cuando algún programador quiere cargar clases internas usando Class.forName(), pero eso es bastante raro ... y la solución es sencilla.

+0

El último párrafo está en el lugar, creo. Java * already * tiene un formato contenedor que puede agrupar múltiples clases (y recursos) en un solo archivo. ¿Por qué introducir la misma característica en otro nivel también? –

12

La JVM debe ser capaz de encontrar el código para una clase determinada, dado su nombre. Si no existe ninguna relación entre el nombre de archivo de origen y el nombre de archivo del código, y desea que el nombre de archivo del código se base en el nombre de archivo , ¿cómo esperaría que cargue el código?

Como ejemplo: supongamos que compilamos Foo.java que contiene la clase Bar.

Otra clase se refiere a Bar, por lo que la JVM necesita el código ... ¿cómo sugieres que encuentre el archivo?

Tenga en cuenta que en .NET hay una unidad de implementación independiente llamada ensamblaje - y una referencia a un tipo también incluye el nombre del ensamblado, pero eso es ligeramente diferente de lo que proponía.

2

Esa es una decisión de diseño con respecto a una unidad de compilación, hecha por los desarrolladores. Las clases compiladas generalmente se combinan en un archivo jar.

Extracto de Java Language Spec

7,3 unidades de compilación CompilationUnit es el símbolo objetivo (§ 2.1) para la gramática sintáctica (§ 2.3) de programas Java.

Los tipos declarados en diferentes unidades de compilación pueden depender uno del otro, circularmente. Un compilador de Java debe organizar para compilar todos esos tipos al mismo tiempo.

Cuestiones relacionadas