reservadas palabras end java goto

palabras - Goto en Java bytecode



goto end java (9)

Información general de fondo:

La parte de hardware de cualquier microprocesador solo sabe que necesita ejecutar sucesivamente cada instrucción comenzando desde una dirección de memoria; ni siquiera sabe en qué dirección de memoria detiene la ejecución de las instrucciones.

El lenguaje ensamblador es un convertidor muy delgado de "comandos" a "microinstrucciones binarias". La lista de "comandos" no incluye instrucciones de flujo de control, todo lo que tiene son instrucciones de salto (saltos simples o saltos condicionales), eso es todo (está bien, hay una instrucción para los bucles sin fin incondicionales y para los bucles condicionales).

Debido a esto, las declaraciones de flujo de control que están disponibles en lenguajes superiores como C se implementan usando estas instrucciones de salto porque no hay otra forma de implementarlas. Como sucede, goto en C se compila en instrucciones binarias como una simple instrucción de salto incondicional.

Justificación de Java y JVM:

Muchas arquitecturas de hardware diferentes tienen estándares / formatos diferentes para "microinstrucciones binarias" y diferentes conjuntos de instrucciones. La JVM tiene su propio estándar y su propio conjunto de instrucciones.

Esto permite al compilador de Java generar siempre las mismas instrucciones sin importar en qué arquitectura de hardware se ejecutará el ejecutable; El trabajo de la JVM es traducir una instrucción de su propio estándar al estándar de la máquina actual.

Así que, en esencia, el código de bytes JVM es un "lenguaje ensamblador" para "la máquina virtual java". Lo que significa que no tiene instrucciones de flujo de control. Tiene instrucciones de salto incondicionales (que se denominan goto ).

break y continue en el nivel más bajo se implementa como un jump (o goto ). El punto del asunto es que si usa un lenguaje de nivel superior, querrá evitar usar goto incluso si está disponible (como en C), y usaría las estructuras de control más legibles.

Hay algunos casos especiales (en C por ejemplo) cuando incluso los programadores que respetan todas las "mejores prácticas de codificación" usarían un goto por ejemplo, implementaciones de coroutine.

Algunos otros ejemplos de sacrificar los estándares de codificación para obtener un rendimiento mejor o más confiable es cuando los desarrolladores de Kernel tienen un código de ensamblaje específico de arquitectura (C le permite escribir instrucciones de ensamblaje).

Así que el otro día, cuando miraba la página de wikipedia para el código de bytes de Java, encontré este ejemplo:

Considere el siguiente código de Java:

outer: for (int i = 2; i < 1000; i++) { for (int j = 2; j < i; j++) { if (i % j == 0) continue outer; } System.out.println (i); }

Un compilador de Java podría traducir el código de Java anterior a un código de bytes de la siguiente manera, asumiendo que lo anterior se puso en un método:

0: iconst_2 1: istore_1 2: iload_1 3: sipush 1000 6: if_icmpge 44 9: iconst_2 10: istore_2 11: iload_2 12: iload_1 13: if_icmpge 31 16: iload_1 17: iload_2 18: irem 19: ifne 25 22: goto 38 25: iinc 2, 1 28: goto 11 31: getstatic #84; //Field java/lang/System.out:Ljava/io/PrintStream; 34: iload_1 35: invokevirtual #85; //Method java/io/PrintStream.println:(I)V 38: iinc 1, 1 41: goto 2 44: return

Y me doy cuenta de que aparece una pequeña palabra goto un par de veces, que al verificar la especificación JVM es válida. Mi pregunta es ¿por qué? GOTO es una palabra clave reservada pero inutilizable en Java, así que ¿por qué cuando escribimos y compilamos el código Java, parece que se compila con goto de nuevo en él? Me pregunto si esta es la forma en que siempre se han hecho las cosas en un nivel inferior de programación, o si se debe a que se confía en que la JVM use la palabra goto de manera más efectiva. En última instancia, tengo curiosidad por saber por qué se considera que goto es una práctica tan mala que está prohibido en el código Java, pero parece que se vuelve a incluir en su código cuando se compila.


  1. SpaceTrucker mencionó (en comentarios a la pregunta principal) una diferencia entre el lenguaje Java y el código de bytes. La palabra clave goto y la instrucción goto no son lo mismo. Lo único común es el nombre. En caso de código de bytes, es solo una instrucción de JUMP ( JMP );
  2. Básicamente, se piensa que goto es una mala práctica en la programación / codificación, debido a que se realiza el código ''spagetti'' y se empeora la legibilidad del código.

Bytecode es una especie de lenguaje ensamblador para la máquina virtual. Es muy común tener instrucciones de salto en lenguaje de máquina. goto es una instrucción de salto incondicional.

El compilador de Java traduce casi todas las declaraciones de flujo de control dentro de un cuerpo de método en instrucciones goto.

La palabra clave goto probablemente se reservó en Java para conservar la opción de agregarla a una versión posterior en caso de que hubiera resultado que su existencia hubiera sido crítica. En realidad, no hay nada malo con goto desde el punto de vista de la máquina. Tiene una mala reputación porque permite escribir código que es muy difícil de leer para un humano. El lenguaje Java le permite usar break y continuar con las etiquetas como un reemplazo para goto.


Debe distinguir entre la palabra clave goto y el código de byte o la instrucción de ensamblaje goto .

Es una mala práctica usar goto jumps en código de alto nivel, como en C. Por lo tanto, no está permitido en Java.

El artículo original de Edsger W. Dijkstra sobre goto .

En el código compilado, el uso de la instrucción de salto incondicional goto es completamente correcto. El compilador lo coloca allí y no se olvida de las implicaciones de saltar alrededor del código, incluida la inicialización de datos, la desasignación de la memoria, etc.


Estás viendo el equivalente de código de máquina de la JVM. Si goto está permitido en Java es irrelevante si está permitido en el bytecode, al igual que los punteros no están permitidos en JVM, pero JVM compilará o interpretará el bytecode en un código de máquina que utiliza punteros.


Las funciones de programación estructurada de Java, como los bucles ( for / while ), se implementan en el nivel de bytecode con instrucciones de derivación condicional ( IF.. ) e salto incondicional ( GOTO ).

break o continue a un bucle externo también se considera lo suficientemente útil y legítimo dentro de la programación estructurada, que el lenguaje Java tiene estas características (romper / continuar etiquetando).

En el nivel de JVM / bytecode, estos también se implementan con GOTO .

Ver:


Las instrucciones Goto en la programación son instrucciones unidireccionales en las que, como las llamadas a funciones, son conmutadores bidireccionales, es decir, volverá a la sección llamada del código.

Para usar esos solo bytecodes usa goto en ellos. En caso de que el usuario pueda usar goto significa que podemos usarlo de una manera ineficiente (por ejemplo, una declaración goto no condicionada) que nunca permitirá que el programa termine.

Jvm es tan inteligente que nunca deja que el programa se ejecute infinitamente.


bytecode no es Java, los programas en otros idiomas, como Groovy, se pueden compilar en bytecode, puede escribir bytecode directamente usando algunas herramientas como BCEL. En cuanto a goto, no puedes ir sin él a un nivel bajo.


goto está bien a nivel de máquina, el compilador java no está escribiendo código, solo convierte el código de la fuente java a bytecode.

Para las personas que escriben código, esta es una historia diferente, las instrucciones de goto son difíciles de leer y analizar y el código es el lío después de muchos saltos. Esta es la razón por la que las personas deberían usar los conceptos de OO en lugar de instrucciones de salto.