2012-02-12 25 views
6

enter link description here ¿Cómo se las arregla el compilador de Java para resolver las referencias entre clases tan rápidamente, si tiene un conjunto de clases que se refieren entre sí y utilizan los métodos de los demás?compiladores + referencias entre clases: ¿cómo hace javac rápidamente lo que los compiladores C++ hacen lentamente?

Sé cómo funcionan los compiladores de C++ en este sentido: cada archivo .cpp se compila por separado, y usan esos terribles archivos .h para declarar campos/métodos de clase, de modo que el mismo conjunto de archivos se vuelve a analizar cada vez y/o los compiladores tienen que soportar encabezados precompilados.

Pero Java no hace esto y no hay separación en el origen del programa de las interfaces de clase/implementaciones de la forma en que Turbo Pascal las separó.

Veo que si tiene una clase Foo y se refiere a las clases Bar, Baz, Quux que están todas en un archivo barbazquux.jar separado, entonces las cosas serían sencillas: el archivo .jar ya se ha compilado, así que cuando Foo.java se compila puede ir a ver los archivos .class en barbazquux.jar.

Pero si tiene referencias de clases cíclicas, y la clase Foo hace referencia a la clase Bar que hace referencia a la clase Foo, ¿cómo compila posiblemente Foo.java sin tener que compilar primero Bar.java y luego decidir que tiene que compilar Foo.java y quedar atrapado en un bucle?

¿Qué hace el compilador de Java para manejar las referencias entre clases?


edición: Yair señala another question con respuestas que vagamente menciones compiladores paso múltiple. De acuerdo, entonces hay múltiples pases. ¿Qué sucede exactamente en cada pase y cómo logra Java compilar tan rápido? ¿Tiene que volver a analizar cada archivo en cada pase, o almacena el árbol de sintaxis abstracta para ahorrar tiempo, o qué?

+0

... y ¿cómo se llama este concepto, por lo que puedo obtener más información si elijo buscar en algunos libros de compilación? –

+0

parece una pregunta de dup que fue respondida. Ver [aquí] (http://stackoverflow.com/questions/3032874/how-does-compiling-circular-dependencies-work). – yair

+0

Supongo, pero esa pregunta realmente no tiene respuestas que dicen mucho. –

Respuesta

-1

La gramática de C++ es mucho más complicada, la expresión es ambigua. Entonces Javac es más eficiente en el análisis. También C++ tiene unidades de compilación de grano más fino. C++ incluye, incluso si está precompilado, una visibilidad recursiva: incluye las inclusiones de incluye nombres definidos que se pueden usar. En Java, si usa la clase principal de una clase importada, es necesario importarla explícitamente.

Las referencias de clases cíclicas son problemáticas. En Java, uno puede, como condición previa, suponer que existe una clase, incluso si esa clase aún no está compilada. Pero el compilador de java es aún más impresionante, pudiendo compilarlos al mismo tiempo. Lo mismo debido a las dependencias cíclicas. El JVM byte code invoke instructions usa nombres de métodos, por lo que uno puede compilar especulativamente la primera clase.

public class A { 
    public static void a(int i) { 
     System.out.println("a(" + i + ")"); 
     if (i < 10) 
      B.b(i + 2); 
    } 
} 

public class B { 
    public static void b(int i) { 
     System.out.println("b(" + i + ")"); 
     if (i < 10) 
      A.a(i + 1); 
    } 
} 

public static void main(String... args) { 
    B.b(0); 
} 
+0

La pregunta no es sobre la eficiencia en el análisis. Se trata de la resolución de las dependencias entre clases. – EJP

0

C++ tiene que analizar el código fuente de una declaración de clase externa, normalmente en un archivo .hpp. Java procesa el código objeto de declaraciones de clase externas, que ya está compilado. Lo que hace Java es más parecido a lo que hacen los idiomas con los paquetes, p. Ada, Modula-3, ... Es por eso que la mayoría de los compiladores C/C++ también tienen 'encabezados precompilados'.

+0

@downvoter Tus razones, por favor – EJP

+0

idk pero he votado positivamente. Tal vez es el archivo ".hpp"; nadie realmente los usa, los archivos C++ también son típicamente archivos ".h". –

Cuestiones relacionadas