2010-08-04 10 views
49

Confundido por proceso de compilación de Java¿Cómo ocurre exactamente la compilación java?

bien sé que esto: Escribimos código fuente de Java, el compilador, que es independiente de la plataforma se traduce en código de bytes, a continuación, la JVM que es dependiente de la plataforma que se traduce en código máquina.

Así que desde el principio, escribimos el código fuente de Java. El compilador javac.exe es un archivo .exe. ¿Qué es exactamente este archivo .exe? ¿No está el compilador de Java escrito en Java, entonces, ¿cómo es que hay un archivo .exe que lo ejecuta? Si el código del compilador está escrito es java, entonces ¿cómo es que el código del compilador se ejecuta en la etapa de compilación, ya que es el trabajo de jvm ejecutar código java? ¿Cómo puede un lenguaje en sí mismo compilar su propio código de idioma? Todo parece un problema de huevo y pollo para mí.

¿Qué contiene exactamente el archivo .class? ¿Es un árbol de sintaxis abstracta en forma de texto, es información tabular, qué es?

alguien me puede decir de manera clara y detallada sobre cómo se convierte mi código fuente de Java en código máquina.

+0

Un idioma puede compilar fácilmente su propio código de idioma. Los compiladores C/C++ a menudo se escriben en C o C++, el compilador de lenguaje cobra está escrito en cobra, y hay muchos ejemplos de compiladores http://en.wikipedia.org/wiki/Self-hosting. – jcao219

+4

El compilador no tiene que ser independiente de la plataforma, solo tiene que cumplir con las especificaciones que solo especifican entrada y salida. Podrías escribir un compilador en perl para todo el bytecode resultante. –

+0

pregunta relacionada con stackoverflow: http://stackoverflow.com/questions/1220914/in-which-language-java-compiler-jvm-and-java-is-written – jvdneste

Respuesta

54

bien sé que esto: Escribimos código fuente de Java, el compilador, que es independiente de la plataforma que se traduce en bytecode,

En realidad, el propio compilador funciona como un ejecutable nativo (de ahí javac.exe) Y es cierto, transforma el archivo fuente en bytecode. El bytecode es independiente de la plataforma, ya que está dirigido a Java Virtual Machine.

luego el jvm que depende de la plataforma lo traduce en código máquina.

No siempre. En cuanto a la JVM de Sun, hay dos jvms: cliente y servidor. Ambos pueden, pero ciertamente no tienen que compilar a código nativo.

Así que desde el principio, escribimos el código fuente de Java. El compilador javac.exe es un archivo .exe. ¿Qué es exactamente este archivo .exe? ¿No está el compilador de Java escrito en Java, entonces, ¿cómo es que hay un archivo .exe que lo ejecuta?

Este archivo exe es un bytecode envuelto de java. Es por conveniencia: para evitar secuencias de comandos complicadas por lotes. Inicia una JVM y ejecuta el compilador.

Si el código del compilador está escrito es java, entonces ¿cómo es que el código del compilador se ejecuta en la etapa de compilación, ya que es el trabajo de jvm ejecutar el código java.

Eso es exactamente lo que hace el código de envoltura.

¿Cómo puede un lenguaje compilar su propio código de idioma? Todo parece un problema de huevo y pollo para mí.

Cierto, confuso a primera vista. Sin embargo, no es solo la expresión idiomática de Java. El compilador de Ada también está escrito en Ada. Puede parecer un "problema de huevo y gallina", pero en realidad solo es un problema de arranque.

¿Qué contiene exactamente el archivo .class? ¿Es un árbol de sintaxis abstracta en forma de texto, es información tabular, qué es?

No es Resumen Sintaxis Árbol. AST solo lo usa el tokenizador y el compilador en el momento de la compilación para representar el código en la memoria. El archivo .class es como un ensamblado, pero para JVM. JVM a su vez es una máquina abstracta que puede ejecutar un lenguaje de máquina especializado, dirigido solo a la máquina virtual. En su forma más simple, el archivo .class tiene una estructura muy similar al ensamblaje normal. Al principio se declaran todas las variables estáticas, luego vienen algunas tablas de firmas de funciones externas y, por último, el código de máquina.

Si es realmente curioso Puede profundizar en el archivo de clase utilizando la utilidad "javap". A continuación se muestra (ofuscado) de salida de invocar javap -c Main:

0: new #2; //class SomeObject 
3: dup 
4: invokespecial #3; //Method SomeObject."<init>":()V 
7: astore_1 
8: aload_1 
9: invokevirtual #4; //Method SomeObject.doSomething:()V 
12: return 

lo que debe tener una idea ya lo que realmente es.

nadie me puede decir de manera clara y detallada cómo se convierte mi código fuente de Java en código máquina.

creo que debería ser más clara en este momento, pero aquí es breve resumen:

  • se invoca javac que apunta al archivo de código fuente. El lector interno (o tokenizer) de javac lee su archivo y crea un AST real a partir de él. Todos los errores de sintaxis provienen de esta etapa.

  • El javac no ha terminado su trabajo todavía. Cuando tiene AST, la compilación verdadera puede comenzar. Utiliza el patrón de visitante para recorrer AST y resuelve dependencias externas para agregar significado (semántica) al código. El producto terminado se guarda como un archivo .class que contiene bytecode.

  • Ahora es el momento de ejecutar la cosa. Invoque java con el nombre de .classfile. Ahora la JVM comienza de nuevo, pero a interprete Su código. La JVM puede, o no puede compilar su código de bytes abstracto en ensamblado nativo. El compilador HotSpot de Sun junto con la compilación Just In Time pueden hacerlo si es necesario. El código de ejecución es constantemente perfilado por la JVM y recompilado al código nativo si se cumplen ciertas reglas. Más comúnmente, el código caliente es el primero en compilar de forma nativa.

Editar: Sin la javac habría que invocar el compilador usando algo similar a esto:

%JDK_HOME%/bin/java.exe -cp:myclasspath com.sun.tools.javac.Main fileToCompile 

Como se puede ver que está llamando a la API privada de Sun por lo que ha obligado a la implementación de Sun JDK. Haría que los sistemas de construcción dependieran de ello. Si se cambia a cualquier otro JDK (el wiki lista 5 además del de Sun), entonces el código anterior debe actualizarse para reflejar el cambio (ya que es poco probable que el compilador resida en el paquete com.sun.tools.javac). Otros compiladores podrían escribirse en código nativo.

Así que la forma estándar es enviar el contenedor javac con JDK.

+2

Así que aquí está el escenario de lo que describió, escribimos el código fuente. javac.exe el ejecutable, principalmente existe para recopilar parámetros y para iniciar la JVM. A continuación, la JVM ejecuta el código del compilador (recopilación de un gran número de archivos .class ya compilados). El compilador luego ejecuta nuestro programa escrito. Además, cuando se estaba diseñando el compilador, se usa otro lenguaje (C en nuestro caso) para crear los archivos .class para el compilador. estoy en lo correcto con lo que dije? ¿El archivo .exe es un bytecode envuelto de Java? No está exactamente envolviendo el código. ¿De qué clase de scripts complicados estás hablando? – nash

+3

Correcto, 'javac' es solo una envoltura conveniente. El código del compilador real está en el paquete 'com.sun.tools.javac' de Sun's JDK. Puedes ir allí y echar un vistazo al código fuente; puede ser interesante ver las partes internas. También puede invocar el compilador 'javac' directamente desde Java, sin llamar a ningún proceso externo. Si toma eso en cuenta, tiene sentido que 'javac' sea solo un iniciador de cierto archivo de clase enterrado dentro de JDK. Solo puedo sospechar, pero creo que hace tan poco como iniciar JVM y pasar los argumentos. – Rekin

+0

Y sobre el script por lotes, eche un vistazo al último párrafo de la respuesta. Lo edité para responder a tu comentario. – Rekin

3

El archivo .class contiene bytecode que es tipo de como muy high-level Assembly. El compilador podría estar escrito en Java, pero la JVM tendría que compilarse en código nativo para evitar el problema del huevo y la gallina. Creo que está escrito en C, al igual que los niveles inferiores de las bibliotecas estándar. Cuando se ejecuta JVM, realiza una compilación justo a tiempo para convertir ese bytecode en instrucciones nativas.

13

No está el compilador de Java escrito en Java, entonces ¿cómo es que hay un archivo .exe que lo ejecuta?

¿De dónde obtienes esta información? El ejecutable javac se puede escribir en cualquier lenguaje de programación, es irrelevante, todo lo que es importante es que es un ejecutable que convierte los archivos .java en archivos .class.

Para más detalles sobre la especificación binaria de un archivo .class que puede encontrar estos capítulos en la Java Language Specification útil (aunque posiblemente un poco técnico):

Usted también puede echar un vistazo a Virtual Machine Specification que cubre:

+0

Verificará los enlaces. Además del escenario que agregué como comentario a la respuesta de rekin. Estoy en lo correcto con eso? – nash

4

Bueno, javac y la JVM son normalmente binarios nativos. Están escritos en C o lo que sea. Sin duda es posible escribirlos en Java, solo necesitas una versión nativa primero. Esto se llama "ajuste de arranque".

Dato curioso: la mayoría de los compiladores que compilan en código nativo están escritos en su propio idioma. Sin embargo, todos tenían que tener una versión nativa escrita en otro idioma primero (generalmente C). El primer compilador de C, en comparación, se escribió en Assembler. Supongo que el primer ensamblador fue escrito en código de máquina.(O bien, using butterflies;)

.Los archivos de clase son bytecode generados por javac. No son textuales, son códigos binarios similares al código máquina (pero con un conjunto de instrucciones y arquitectura diferentes).

El jvm, en tiempo de ejecución, tiene dos opciones: puede interpretar el código de bytes (pretendiendo ser una CPU), o puede JIT (just-in-time) compilarlo en código máquina nativo. Este último es más rápido, por supuesto, pero más complejo.

+0

Gracias por el XKCD ..no lo había visto :) –

+0

Técnicamente, el primer compilador podría ser creado por un * intérprete * escrito en otro idioma, aunque las líneas entre la interpretación y la compilación JIT son un poco borrosas ya que en última instancia ambos producen código de máquina nativo. –

+0

Es cierto. De hecho, hay opciones aún más locas. El primer compilador de C++ fue simplemente un traductor que produjo el código C para usar con un compilador de C. –

-1

El compilador fue escrito originalmente en C con bits de C++ y supongo que todavía lo es (¿por qué crees que el compilador también está escrito en Java?). javac.exe es solo el código C/C++ que es el compilador.

Como comentario adicional, puede escribir el compilador en Java, pero tiene razón, debe evitar el problema del huevo y la gallina. Para hacer esto, normalmente escribiría una o más herramientas de arranque en algo como C para poder compilar el compilador.

El archivo .class contiene los códigos de bytes, el resultado del proceso de compilación javac y estas son las instrucciones que le indican a la JVM qué hacer. En tiempo de ejecución, estos códigos de bytes se han traducido a instrucciones de CPU nativas (código de máquina) para que puedan ejecutarse en el hardware específico bajo la JVM.

Para complicar esto un poco, la JVM también optimiza y almacena en caché el código de máquina producido a partir de los códigos de bytes para evitar traducirlos repetidamente. Esto se conoce como compilación JIT y ocurre cuando el programa se está ejecutando y se están interpretando bytecodes.

+2

Es ampliamente conocido que el compilador de Java (Sun/Oracle) está escrito en Java. Desde Java 6, incluso hay una API suficiente para ello, pero mucho antes de eso, la gente lo llamaba a través de la API no oficial en los paquetes sun.tools. –

+0

Bueno, aprendes algo nuevo todos los días. – Paolo

10

El compilador javac.exe es un archivo .exe. ¿Qué es exactamente este archivo .exe? ¿No es el compilador de java escrito en java, , entonces, ¿cómo es que hay un archivo .exe que lo ejecuta ?

El compilador de Java (al menos el que viene con Sun/Oracle JDK) está escrito en Java. javac.exe es solo un iniciador que procesa los argumentos de línea de comandos, algunos de los cuales se pasan a la JVM que ejecuta el compilador, y otros al compilador.

Si el compilador de código que se escribe es java, entonces ¿cómo es que el código del compilador es ejecutada en la etapa de compilación, ya que su el trabajo de la JVM para ejecutar código Java . ¿Cómo puede un lenguaje compilar su propio código de idioma? Todo parece un problema de pollo y huevo para mí.

Muchos (si no la mayoría) de los compiladores están escritos en el idioma que compilan. Obviamente, en una etapa temprana el compilador tuvo que ser compilado por otra cosa, pero después de ese "arranque", cualquier versión nueva del compilador puede ser compilada por una versión anterior.

¿Qué contiene exactamente el archivo .class ? ¿Es un árbol de sintaxis abstracta en forma de texto, es información tabular , qué es?

Los detalles del formato de archivo de clase se describen en el Java Virtual Machine specification.

+0

"El compilador de Java (al menos el que viene con Sun/Oracle JDK) está escrito en Java" ¡No lo sabía! Gracias Señor. – ZoFreX

1

Windows no sabe cómo invocar programas Java antes de instalar un tiempo de ejecución Java, y Sun eligió comandos nativos que recopilan argumentos y luego invocan la JVM en lugar de vincular el sufijo jar al motor Java.

+0

No en CMD.EXE hasta donde yo sé. No puedes simplemente decir "foobar.jar" en la línea commadn y hacer que se ejecute. Esto podría ser una limitación de Windows 95/98/ME en COMMAND.EXE que dio como resultado esa decisión. Estos días sería bueno sin embargo. –

-3
  1. archivo .java
  2. compilador (construcción Java)
  3. .class (código de bytes)
  4. JVM (software del sistema general de construir con 'C')
  5. OPERATIVO PLATAFORMA
  6. PROCESADOR
2

Breve explicación

Escriba el código en un editor de texto, guárdelo en un formato que el compilador entienda - ".java " extensión de archivo, javac (compilador Java) convierte esta a " .class" archivo de formato (código de bytes - archivo de clase). JVM ejecuta el archivo .class en el sistema operativo que se sienta en

.

larga explicación

recordar siempre Java no es el idioma base de que el sistema operativo reconoce. código fuente de Java se interpreta para el sistema operativo por un traductor llamado Java virtual Machine (JVM). JVM puedo entender la código en el que escribe un editor, necesita un código compilado. Aquí es donde un compilador entra en la imagen.

Cada proceso de la computadora se entrega a la manipulación de la memoria. No podemos simplemente escribir código en un editor de texto y compilarlo. Necesitamos ponerlo en la memoria de la computadora, es decir, guardarlo antes de compilar.

¿Cómo el javac (compilador de Java) reconocerá el texto guardado como el que se va a compilar? - Tenemos un formato de texto separado que el compilador reconoce, es decir, .java. Guarde el archivo en la extensión .java y el compilador lo reconocerá y compilará cuando se le solicite.

¿Qué ocurre durante la compilación? - El compilador es un segundo traductor (no un término técnico) involucrado en el proceso, traduce el lenguaje entendido por el usuario (java) en un lenguaje entendido por JVM (código de byte - formato de clase).

¿Qué ocurre después de la compilación? - El compilador produce un archivo .class que JVM entiende. El programa se ejecuta entonces, es decir, JVM ejecuta el archivo .class en el sistema operativo.

hechos que debe saber

1) Java no es multiplataforma es independiente de la plataforma .

2) JVM se desarrolla utilizando C/C++. Una de las razones por las que las personas llaman a Java un lenguaje más lento que C/C++

3) El código de bytes de Java (.class) está en "Assembly Language", el único idioma que entiende JVM. Cualquier código que produzca un archivo .class en compilación o código Byte generado se puede ejecutar en la JVM.

Cuestiones relacionadas