Java, al ser un lenguaje de programación independiente de la plataforma, no funciona en la compilación de un solo paso. En cambio, implica una ejecución de dos pasos, primero a través de un compilador independiente del sistema operativo; y segundo, en una máquina virtual (JVM) que está hecha a medida para cada sistema operativo.
Las dos etapas principales se explican a continuación:
Principio 1: Compilación
Primero, el archivo fuente ‘.java’ se pasa a través del compilador, que luego codifica el código fuente en una codificación independiente de la máquina, conocida como Bytecode. El contenido de cada clase contenida en el archivo fuente se almacena en un archivo ‘.class’ separado. Al convertir el código fuente en el código de bytes, el compilador sigue los siguientes pasos:
Paso 1: Analizar : lee un conjunto de archivos fuente *.java y mapea la secuencia del token resultante en Nodes AST (Árbol de sintaxis abstracta).
Paso 2: Ingresar : Ingresa símbolos para las definiciones en la tabla de símbolos.
Paso 3: Procesar anotaciones: si se solicita, procesa las anotaciones que se encuentran en las unidades de compilación especificadas.
Paso 4: Atributo : Atribuye los árboles de sintaxis. Este paso incluye la resolución de nombres, la verificación de tipos y el plegado constante.
Paso 5: Flujo : realiza un análisis de flujo de datos en los árboles del paso anterior. Esto incluye comprobaciones de asignaciones y accesibilidad.
Paso 6: Desugar : Reescribe el AST y traduce algo de azúcar sintáctico.
Paso 7: Generar : genera archivos ‘.Class’.
Principio 2: Ejecución
Los archivos de clase generados por el compilador son independientes de la máquina o del sistema operativo, lo que permite ejecutarlos en cualquier sistema. Para ejecutar, el archivo de clase principal (la clase que contiene el método principal) se pasa a la JVM y luego pasa por tres etapas principales antes de que se ejecute el código de máquina final. Estas etapas son:
Estos estados incluyen:
- cargador de clases
- Verificador de código de bytes
- Compilador justo a tiempo
Hablemos de las 3 etapas.
Etapa 1: cargador de clases
La clase principal se carga en la memoria sin pasar por su archivo ‘.class’ a la JVM, mediante la invocación de este último. Todas las demás clases a las que se hace referencia en el programa se cargan a través del cargador de clases.
Un cargador de clases, en sí mismo un objeto, crea un espacio de nombres plano de cuerpos de clases a los que se hace referencia mediante un nombre de string. La definición del método se proporciona debajo de la ilustración de la siguiente manera:
Ilustración:
// loadClass function prototype Class r = loadClass(String className, boolean resolveIt); // className: name of the class to be loaded // resolveIt: flag to decide whether any referenced class should be loaded or not.
Hay dos tipos de cargadores de clases.
- primordial
- no primordial
El cargador de clases primordial está integrado en todas las JVM y es el cargador de clases predeterminado. Un cargador de clases no primordial es un cargador de clases definido por el usuario, que se puede codificar para personalizar el proceso de carga de clases. El cargador de clases no primordial, si está definido, se prefiere al predeterminado para cargar clases.
Etapa 2: Verificador de código de bytes
Después de que el cargador de clases carga el código de bytes de una clase, debe ser inspeccionado por el verificador de códigos de bytes, cuyo trabajo es verificar que las instrucciones no realicen acciones dañinas. Los siguientes son algunos de los controles realizados:
- Las variables se inicializan antes de ser utilizadas.
- Las llamadas a métodos coinciden con los tipos de referencias a objetos.
- No se violan las reglas para acceder a datos y métodos privados.
- Los accesos a variables locales se encuentran dentro de la pila de tiempo de ejecución.
- La pila en tiempo de ejecución no se desborda.
- Si alguna de las comprobaciones anteriores falla, el verificador no permite que se cargue la clase.
Etapa 3: compilador justo a tiempo
Esta es la etapa final que encuentra el programa java, y su trabajo es convertir el bytecode cargado en código de máquina. Cuando se usa un compilador JIT, el hardware puede ejecutar el código nativo, en lugar de que la JVM interprete la misma secuencia de código de bytes repetidamente e incurra en la penalización de un proceso de traducción relativamente largo. Esto puede conducir a mejoras de rendimiento en la velocidad de ejecución, a menos que los métodos se ejecuten con menos frecuencia.
El proceso se puede ilustrar bien con el siguiente diagrama, como se muestra arriba, a partir del cual llegamos a la conclusión.
Conclusión: debido al proceso de ejecución de dos pasos descrito anteriormente, un programa Java es independiente del sistema operativo de destino. Sin embargo, debido a lo mismo, el tiempo de ejecución es mucho mayor que el de un programa similar escrito en un programa compilado dependiente de la plataforma.
Implementación:
Considere que el programa de impresión simple está escrito en algún lugar del directorio local en una máquina.
Java
// Java Program to Illustrate Compilation and Execution // Stages // Main class class GFG { // Main driver method public static void main(String[] args) { // Print command System.out.print("Welcome to Geeks"); } }
Welcome to Geeks
Entendamos el proceso real de compilación y ejecución.
Paso 1: Vamos a crear un archivo escribiendo un código de impresión simple en un archivo de texto y guardándolo con la extensión “.java”.
Paso 2: abra la terminal (aquí estamos usando macOS) y vaya al directorio del escritorio usando el siguiente comando de la siguiente manera.
cd /Users/mayanksolanki/GFG.java
Paso 3: Tratemos de compilar nuestro programa con el siguiente comando
javac GFG.java
Paso 4: Por último, ejecútelo con el siguiente comando de la siguiente manera:
java GFG
Nota: el archivo GFG.class se crea después del tercer paso, lo que significa que ahora todo nuestro código en el lenguaje de programación Java está cifrado de forma segura, ya que solo contiene binarios. En el paso 4 estamos ejecutando ese archivo. Consulte los siguientes medios para facilitar la comprensión.