¿Hay una declaración goto en Java?


259

Estoy confundido acerca de esto. A la mayoría de nosotros nos han dicho que no hay ninguna declaración goto en Java.

Pero descubrí que es una de las palabras clave en Java. ¿Donde puede ser usado? Si no se puede usar, ¿por qué se incluyó en Java como palabra clave?


13
Sólo una palabra de consejo: nunca utilizar Goto
lostiniceland

16
Y luego está "'Ir a la declaración se considera dañino' se considera dañino" y "'" Ir a la declaración se considera nocivo "Se considera nocivo" ¿Se considera nocivo? " VEEEEERY recursivo, este meme.
Chris Charabaruk

70
'goto' siempre es malo, como en 'goto work' o 'goto school';)
Andreas Dolk el

24
La verdadera razón es que la palabra "g ** o" se considera obscena en la mayoría de los lenguajes de programación. Los diseñadores de Java solo protegen a los programadores jóvenes inocentes de las influencias corruptoras. (:-))
Stephen C

25
La caza de brujas contra goto ha generado algunos de los momentos más agravantes de mi vida. He visto personas contorsionar el código C al ocultar la funcionalidad en las funciones, poner una lógica de salida absurda en bucles multi-anidados y, de lo contrario, realizar todas las formas de ingeniería excesiva imaginables SOLO para evitar que alguien critique su código en una revisión de código. Esta regla, junto con el canard "debes evitar los retornos múltiples", está llena de tonterías. Hay momentos en que goto hace que las cosas sean menos mantenibles. Hay momentos en que goto hace las cosas más fáciles de mantener. Esperaba que esta caza de brujas hubiera muerto en los años 80.

Respuestas:


200

La lista de palabras clave de Java especifica la gotopalabra clave, pero está marcada como "no utilizada".

Estaba en la JVM original (ver respuesta de @VitaliiFedorenko ), pero luego se eliminó. Probablemente se mantuvo como una palabra clave reservada en caso de que se agregara a una versión posterior de Java.

Si gotono estaba en la lista y luego se agrega al idioma, el código existente que usaba la palabra gotocomo identificador (nombre de la variable, nombre del método, etc.) se rompería. Pero debido a que gotoes una palabra clave, dicho código ni siquiera se compilará en el presente, y sigue siendo posible hacer que realmente haga algo más adelante, sin romper el código existente.


29
This was probably done in case it were to be added to a later version of Java.En realidad, la razón principal es un poco diferente (ver mi respuesta a continuación)
Vitalii Fedorenko

2
Esa es información buena e interesante, pero no explica por qué sigue siendo una palabra clave reservada.
Thomas

@Thomas ¿No describiste por qué está reservado? Es una palabra clave, por lo que no se puede usar ahora; Más tarde, Goto podría cobrar vida sin causar problemas. Si no fuera una palabra reservada, podría usarse ahora para producir código (int goto = 2;) que se rompería si se introdujera goto.

230

James Gosling creó la JVM original con soporte de gotodeclaraciones, pero luego eliminó esta característica como innecesaria. La razón principal gotoes innecesaria es que generalmente se puede reemplazar con declaraciones más legibles (como break/continue) o extrayendo un fragmento de código en un método.

Fuente: James Gosling, sesión de preguntas y respuestas


24
"... o extrayendo un fragmento de código en un método", eso debe ser muy bueno sin la eliminación adecuada de llamadas de cola.
Nombre para mostrar

45
A veces, un uso juicioso de goto es la forma más fácil y clara de expresar algo, por lo que forzarlo a cualquier otra cosa es menos legible .
Deduplicador

1
@Deduplicator El uso de goto, por muy juicioso que sea, siempre es propenso a errores.
Çelebi Murat

@Deduplicator El único uso de goto considerado buena práctica en C ++ está respaldado por el descanso / continuar.
Invierno

2
Ir a ser una palabra clave reservada en Java es excelente porque evita que las personas nombren las etiquetas "goto:".
Invierno

147

La palabra clave existe, pero no está implementada.

La única buena razón para usar goto que se me ocurre es esta:

for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        goto outsideloops; // to break out of both loops
    }
}
outsideloops:

En Java puedes hacer esto así:

loops:
for (int i = 0; i < MAX_I; i++) {
    for (int j = 0; j < MAX_J; j++) {
        // do stuff
        break loops;
    }
}

1
@ Zoltán No: redirige el código a la etiqueta, justo antes del primer bucle.
Assylias

21
@assylias Bueno, no del todo. La etiqueta etiqueta el bucle externo. Entonces break loopssignifica "salir del ciclo llamado loops". Tal vez en retrospectiva, podría haber sido un mejor nombre para la etiqueta outer.
jonnystoten

8
"La única buena razón para usar goto" Los pequeños programas rápidos y sucios que necesitan un bucle infinito incondicional hacen un gran uso de goto. Usar while (true) {... }es exagerado. GOTO es frecuentemente estigmatizado por sus usos inapropiados, pero sostengo que las comparaciones innecesarias con los literales booleanos son peores que GOTO.
Alexander - Restablece a Mónica el

1
¿No debería la etiqueta de bucles estar detrás de los bucles?
GC_

1
Recientemente descubrí que esta técnica de etiquetado también es muy útil en combinación con una continue LABEL;declaración. Por lo tanto, puede continuar un bucle de mentira exterior.
infotoni91


29

Entonces podrían usarse algún día si los diseñadores de idiomas sintieran la necesidad.

Además, si los programadores de lenguajes que tienen estas palabras clave (por ejemplo, C, C ++) las usan por error, entonces el compilador de Java puede dar un mensaje de error útil.

O tal vez fue solo para detener a los programadores que usan goto :)


La funcionalidad de goto que falta en Java debería ser motivo suficiente para no usar goto: no es necesario reservarla como palabra clave. Después de que la lógica, todo sería una palabra clave, ya que es bien utilizado por otras lenguas y los diseñadores o / Java podría utilizarlo en el futuro ...
Stuxnet

1
No creo que mi lógica implique que todo sería una palabra clave. Hay un pequeño conjunto de palabras clave en uso en muchos lenguajes de programación que pueden detectarse y manejarse de manera útil en Java. Java se reservó gotoy constreflejó su herencia C / C ++, pero siguen sin implementarse (aunque ha habido debates sobre la implementación de este último). A un par más les gusta asserty enumno estaban inicialmente reservados, pero quizás deberían haberlo sido, dado que se han implementado. Pero la retrospectiva es algo maravilloso.
Dave

19

Están reservados para uso futuro (ver: Palabras clave del lenguaje Java )

Las palabras clave const y goto están reservadas, aunque no se usan actualmente.

La razón por la cual no hay una declaración goto en Java se puede encontrar en " El entorno del lenguaje Java ":

Java no tiene declaración goto. Los estudios ilustraron que goto se usa (mal) con mayor frecuencia que simplemente "porque está ahí". La eliminación de goto condujo a una simplificación del lenguaje: por ejemplo, no hay reglas sobre los efectos de un goto en el medio de una declaración for. Los estudios en aproximadamente 100,000 líneas de código C determinaron que aproximadamente el 90 por ciento de las declaraciones goto se usaron exclusivamente para obtener el efecto de romper bucles anidados. Como se mencionó anteriormente, romper y continuar en varios niveles elimina la mayor parte de la necesidad de declaraciones goto.


gotoestá reservado, pero no para uso futuro.
Marqués de Lorne

17

Un ejemplo de cómo usar las etiquetas "continuar" en Java es:

public class Label {
    public static void main(String[] args) {
        int temp = 0;
        out: // label
        for (int i = 0; i < 3; ++i) {
            System.out.println("I am here");
            for (int j = 0; j < 20; ++j) {
                if(temp==0) {
                    System.out.println("j: " + j);
                    if (j == 1) {
                        temp = j;
                        continue out; // goto label "out"
                    }
                }
            }
        }
        System.out.println("temp = " + temp);
    }
}

Resultados:

I am here // i=0
j: 0
j: 1
I am here // i=1
I am here // i=2
temp = 1

10

Es importante comprender que la gotoconstrucción es remanente desde los días que los programadores programaron en código máquina y lenguaje ensamblador. Debido a que esos lenguajes son tan básicos (como en cada instrucción hace solo una cosa), el flujo de control del programa se realiza completamente con gotodeclaraciones (pero en lenguaje ensamblador, se denominan salto o ramificación instrucciones de ).

Ahora, aunque el lenguaje C es de nivel bastante bajo, puede considerarse como un lenguaje ensamblador de muy alto nivel: cada declaración y función en C se puede dividir fácilmente en instrucciones en lenguaje ensamblador. Aunque el C no es el lenguaje principal para programar computadoras hoy en día, todavía se usa mucho en aplicaciones de bajo nivel, como los sistemas integrados. Debido a que la función de C refleja tan estrechamente la función del lenguaje ensamblador, tiene sentidogoto esté incluida en C.

Está claro que Java es una evolución de C / C ++. Java comparte muchas características de C, pero abstrae muchos más detalles y, por lo tanto, simplemente se escribe de manera diferente. Java es un lenguaje de muy alto nivel, por lo que simplemente no es necesario tener características de bajo nivel, como gotocuando hay más construcciones de alto nivel como funciones, para, para cada uno, y mientras los bucles hacen el flujo de control del programa. Imagina si estuvieras en una función e hicieras ungoto una etiqueta en otra función. ¿Qué pasaría cuando volviera la otra función? Esta idea es absurda.

Esto no responde necesariamente por qué Java incluye la gotodeclaración, pero no lo deja compilar, pero es importante saber por qué gotose usó en primer lugar, en aplicaciones de nivel inferior, y por qué simplemente no tiene sentido ser utilizado en Java


"el flujo de control del programa se realiza completamente con goto". Bueno, no siempre goto incondicional.
Peter Mortensen

Saltar con "goto" de una función a una etiqueta en otra función tampoco es posible en C / C ++. Goto en C / C ++ está restringido a un solo bloque de funciones.
user2328447

"simplemente no es necesario tener características de bajo nivel como goto cuando hay más construcciones de alto nivel" - recuerda "Necesidad y suficiencia". Simplemente "no es necesario". Y por lo tanto no hay razón. Lo que ES una razón: "Ir a" como un sustituto de "alto nivel" para los JMP de ensamblador, BNEs y más es razonable si desea saltar al "código ejecutable" pero Java es bytecode y, por lo tanto, no "ejecutable". ;-)
reichhart

10

No, gotono se utiliza, pero puede definir etiquetas y dejar un bucle hasta la etiqueta. Puede usar breako continueseguido por la etiqueta. Para que pueda saltar más de un nivel de bucle. Echa un vistazo al tutorial .


9

No, afortunadamente, no hay gotoen Java.

La gotopalabra clave solo está reservada, pero no se usa (lo mismo ocurre con const).


¿Puedo saber qué significaba el reservado aquí? Si usar goto y const en código no es una buena práctica, ¿por qué lo reservan? ¿Puede usted explicar por favor?
Gopi

@Sri Kumar: vea la respuesta de @ applechewer, existe pero no está implementado.
Valentin Rocher

1
@Sri Kumar: las palabras clave reservadas evitan que se usen como nombres de variables o similares. De esta forma, estas palabras clave se pueden implementar en futuras versiones de Java sin romper el código fuente antiguo que de otra manera podría haberlas usado.
Peter Di Cecco

8

Porque no es compatible y por qué querría una gotopalabra clave que no hizo nada o una variable llamadagoto ?

Aunque puede usar break label;y continue label;declaraciones para hacer efectivamente lo que gotohace. Pero no lo recomendaría.

public static void main(String [] args) {

     boolean t = true;

     first: {
        second: {
           third: {
               System.out.println("Before the break");

               if (t) {
                  break second;
               }

               System.out.println("Not executed");
           }

           System.out.println("Not executed - end of second block");
        }

        System.out.println("End of third block");
     }
}

10
-1 ¿Por qué no se me debe permitir tener una variable o método llamado goto?
Michael Borgwardt

44
Porque tiene un significado en el campo de la programación que no es aplicable a Java. También es una mala elección del nombre de la variable.
pjp

¿Para qué se usaría una variable 'imprimir'? Las palabras que ha mencionado se parecen más a nombres de métodos que a variables o palabras clave.
pjp

3
-1: En primer lugar, el hecho de que Java no sea compatible con la declaración de control de flujo "goto" no significa que esa sea la razón por la que tiene la palabra clave "goto" que no hace nada. En segundo lugar, "goto" podría ser un nombre de variable pobre, pero puede ser un nombre de método excelente, que no podemos usar porque "goto" es una palabra clave. En tercer lugar, "rotular etiqueta" y "continuar etiqueta" existen por una muy buena razón, por lo que "no recomendarlo" no es muy útil. Y cuarto, dado que Sun dice que "actualmente no se usa", lo más probable es que alguna vez planearon implementarlo, pero no quisieron deshacerse de la palabra clave cuando decidieron lo contrario.
Vojislav Stojkovic

2
@VojislavStojkovic Eso es una locura. 1) Que es por eso que no hace nada es porque no lo soporta. Según el JLS, The keywords const and goto are reserved, even though they are not currently used. This may allow a Java compiler to produce better error messages if these C++ keywords incorrectly appear in programs.esto significa "No lo usamos, así que si vienes de un entorno C ++ no te dejaremos usarlo en absoluto". 2) gotoes un nombre de método terrible. Lo siento. 3) se recomienda romper y continuar, pero no en la forma en que se usa aquí . 4) "más probable" [cita requerida].
corsiKa

7

No, gotono se usa en Java, a pesar de ser una palabra reservada. Lo mismo es cierto para const. Ambos se usan en C ++, que es probablemente la razón por la que están reservados; la intención probablemente fue evitar confundir a los programadores de C ++ que migran a Java, y quizás también mantener la opción de usarlos en revisiones posteriores de Java.


1
Realmente espero que gotoal menos no sea compatible en el futuro cercano;)
Bozho

66
@Bozho: bueno, podría usarse para alguna nueva característica ingeniosa que no tiene absolutamente nada que ver con el viejo y dañino goto "dañino".
Michael Borgwardt

3

Tenga en cuenta que puede reemplazar la mayoría de los usos benignos de goto por

  • regreso

  • descanso

  • rotura de etiqueta

  • tirar adentro try-catch-finally


55
Excepciones, NUNCA deben utilizarse para el control de flujo
ChssPly76

13
Las excepciones se usan para el control de flujo, pero deben usarse solo para casos excepcionales. Por ejemplo, uno de los usos de goto en C es el manejo de errores, especialmente si implica la limpieza.
starblue

2
@starblue, me sacaste las palabras de la boca. Lanzar una excepción es el flujo de control. En C, de hecho, puede implementar de manera limpia el manejo de excepciones a través de setjmp / longjmp asegurándose de establecer primero jj en el código de manejo y ejecutar longjmp () en excepción.

Quiero hacer una comprobación if y omitir la mitad del método si es verdadero. Sin ir a debo usar un gigante más. En mi opinión, es bastante feo ya que demasiada parálisis crea confusión
WVrock

1
@WVrock Podrías intentarloreturn
Andrew Lazarus

2

Como se señaló, no existe gotoen Java, pero la palabra clave se reservó en caso de que Sun quisiera agregar gotoa Java algún día. Querían poder agregarlo sin romper demasiado código, por lo que reservaron la palabra clave. Tenga en cuenta que con Java 5 agregaron elenum palabra clave y tampoco rompió tanto código.

Aunque Java no tiene goto, tiene algunas construcciones que corresponden a algunos usos de goto, es decir, poder breaky continuecon bucles con nombre. Además, finallypuede considerarse como una especie de retorcido goto.


1

Prohibir declaraciones de variables con el mismo nombre.

p.ej int i = 0, goto;


3
Pero por que ? ¿Por qué no se nos debe permitir hacer estas declaraciones?
ApproachingDarknessFish

1

Se considera en gran medida una de esas cosas que no debes hacer, pero probablemente se mencionó como una palabra reservada para evitar confusiones para los desarrolladores.


1

http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.goto

Si le han dicho que no hay una declaración goto en Java, se ha engañado. De hecho, Java consta de dos capas de código 'fuente'.


55
es como decir que cualquier idioma tiene un goto porque existe una rama incondicional en el código de ensamblaje debajo de todo. Tener el goto en el código de bytes no significa que haya un goto en java porque "en java" significa "en el lenguaje java", y el código de bytes no es una capa de fuente.

@ tgm1024, "en Java" también se puede interpretar como "en la plataforma Java". El compilador de Java necesita producir código de bytes de Java o la salida no funcionará en la plataforma Java JVM. C ++, por ejemplo, no especifica la salida de compilación y el compilador es libre de producir cualquier forma de código de máquina (o cualquier otro código). La aplicación programada de código de bytes de Java se puede llamar "aplicación Java", pero la aplicación programada de código de máquina no se puede llamar "aplicación C ++".
Mikael Lindlöf

2
Sé muy bien qué es el bytecode de Java. Estaba codificando por primera vez en Java en 1996. Y puede hacer que otros lenguajes generen código de bytes de Java para la JVM. Donde te estoy corrigiendo es esta idea de que hay dos capas de fuente. No hay. Tiene fuente java y esto se compila en código de bytes java (ejecutado por la JVM) y esta no es una capa de fuente adicional. El hecho de que haya un "goto" en el código de bytes no significa que haya un "goto" en Java. Java ha nombrado descansos y nombrado continúa, pero no ha pasado.

@ tgm1024 Me despertó un voto negativo :) Puede parecer fácilmente que perdí el argumento desde que hizo el último comentario y sus credenciales son impresionantes. Mi punto, que estaba construyendo, era que es muy posible programar con código de bytes Java. Para asegurarle, aquí hay incluso una pregunta al respecto: stackoverflow.com/questions/3150254/…
Mikael Lindlöf


1

No soy fan de goto ellos, ya que generalmente hace que el código sea menos legible. Sin embargo, creo que hay excepciones a esa regla (¡especialmente cuando se trata de lexers y analizadores!)

Por supuesto, siempre puede llevar su programa a Kleene Normalform traduciéndolo a algo parecido a un ensamblador y luego escribir algo como

int line = 1;
boolean running = true;
while(running)
{
    switch(line++)
    {
        case 1: /* line 1 */
                break;
        case 2: /* line 2 */
                break;
        ...
        case 42: line = 1337; // goto 1337
                break;
        ...
        default: running = false;
                break;
    }
}

(Así que básicamente escribes una VM que ejecuta tu código binario ... donde line corresponde al puntero de instrucción)

Eso es mucho más legible que el código que usa goto, ¿no?


Siguiente pregunta, "¿Hay una declaración de cambio en Python"
Mark K Cowan

0

Por supuesto, es una palabra clave, pero no se usa en el nivel del código fuente.

Pero si usa jasmin u otro lenguaje de nivel inferior, que se transforma en bytecode, entonces "goto" está ahí


-1

Porque aunque el lenguaje Java no lo usa, JVM bytecode sí.


77
Entonces, ¿por qué el idioma no tiene una loadpalabra clave?
ApproachingDarknessFish

3
@gribnit, tener un goto en bytecode no significa nada para las palabras reservadas de nivel superior.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.