Existe-t-il une instruction goto en Java?


259

Je suis confus à ce sujet. La plupart d'entre nous ont appris qu'il n'y a aucune instruction goto en Java.

Mais j'ai trouvé que c'est l'un des mots clés de Java. Où peut-il être utilisé? S'il ne peut pas être utilisé, pourquoi a-t-il été inclus dans Java comme mot-clé?


13
juste un conseil: n'utilisez jamais goto
lostiniceland

16
Et puis il y a "'Aller à la déclaration considérée comme nuisible' considérée comme nuisible" et "'" Aller à la déclaration considérée comme nuisible "Considérée comme nuisible' Considérée comme nuisible?" VEEEEERY récursif, ce mème.
Chris Charabaruk

70
'goto' est toujours diabolique - comme dans 'goto work' ou 'goto school';)
Andreas Dolk

24
La vraie raison est que le mot "g ** o" est considéré comme obscène dans la plupart des langages de programmation. Les concepteurs Java protègent simplement de jeunes programmeurs innocents contre les influences corrompues. (:-))
Stephen C

25
La chasse aux sorcières contre goto a engendré certains des moments les plus aggravants de ma vie. J'ai vu des gens déformer le code C en cachant la fonctionnalité dans les fonctions, mettre la logique de sortie absurde dans des boucles multi-imbriquées, et sinon faire toutes les formes de suringénierie imaginables JUSTE pour éviter que quelqu'un ne critique leur code dans une révision de code. Cette règle, ainsi que le canard "tu dois éviter les retours multiples", est imprégnée de non-sens. Il y a des moments où goto rend les choses moins faciles à maintenir. Il y a des moments où goto rend les choses plus faciles à maintenir. J'espérais tellement que cette chasse aux sorcières serait morte dans les années 80.

Réponses:


200

La liste des mots clés Java spécifie le gotomot clé, mais il est marqué comme "non utilisé".

Il était dans la JVM d'origine (voir la réponse de @VitaliiFedorenko ), mais a ensuite été supprimé. Il a probablement été conservé comme mot clé réservé au cas où il serait ajouté à une version ultérieure de Java.

S'il goton'était pas sur la liste, et qu'il est ajouté à la langue plus tard, le code existant qui utilisait le mot gotocomme identifiant (nom de variable, nom de méthode, etc ...) se briserait. Mais comme gotoc'est un mot-clé, un tel code ne se compilera même pas dans le présent, et il reste possible de le faire réellement faire quelque chose plus tard, sans casser le code existant.


29
This was probably done in case it were to be added to a later version of Java.En fait, la raison principale est un peu différente (voir ma réponse ci-dessous)
Vitalii Fedorenko

2
Ces informations sont bonnes et intéressantes, mais elles n'expliquent pas pourquoi il s'agit toujours d'un mot clé réservé.
Thomas

@Thomas N'avez-vous pas expliqué pourquoi il est réservé? C'est un mot-clé, il ne peut donc pas être utilisé maintenant; plus tard, goto pourrait prendre vie sans causer de problèmes. Si ce n'était pas un mot réservé, il pourrait être utilisé maintenant pour produire du code (int goto = 2;) qui se briserait si goto était introduit.

230

James Gosling a créé la JVM d'origine avec le support des gotoinstructions, mais il a ensuite supprimé cette fonctionnalité comme inutile. La raison principale goton'est pas nécessaire, car elle peut généralement être remplacée par des instructions plus lisibles (comme break/continue) ou en extrayant un morceau de code dans une méthode.

Source: James Gosling, session de questions / réponses


24
"... ou en extrayant un morceau de code dans une méthode" - cela doit être très cool sans élimination appropriée des appels de queue.
Nom d'affichage

45
Parfois, une utilisation judicieuse de goto est la façon la plus simple et la plus claire d'exprimer quelque chose, donc le forcer à autre chose est forcément moins lisible .
Déduplicateur

1
@Deduplicator L'utilisation de goto, aussi judicieuse soit-elle, est toujours sujette à erreur.
Çelebi Murat

@Deduplicator La seule utilisation de goto considérée comme une bonne pratique en C ++ est soutenue par le break / continue.
Hiver

2
Goto étant un mot clé réservé en Java est génial car il empêche les gens de nommer les étiquettes "goto:".
Hiver

147

Le mot clé existe, mais il n'est pas implémenté.

La seule bonne raison d'utiliser goto à laquelle je peux penser est la suivante:

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, vous pouvez faire ceci comme ceci:

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

1
@ Zoltán Non - il redirige le code vers l'étiquette, juste avant la première boucle.
assylias

21
@assylias Eh bien, pas tout à fait. L'étiquette étiquette la boucle extérieure. Signifie alors break loops"sortir de la boucle appelée loops". Peut-être rétrospectivement aurait-il pu être un meilleur nom pour le label outer.
jonnystoten

8
"La seule bonne raison d'utiliser goto" Les petits programmes rapides et sales qui nécessitent une boucle infinie inconditionnelle font bon usage de goto. Utiliser while (true) {... }c'est exagéré. GOTO est fréquemment stigmatisé pour ses utilisations inappropriées, mais je soutiens que des comparaisons inutiles avec les littéraux booléens sont pires que GOTO.
Alexander - Reinstate Monica

1
L'étiquette des boucles ne devrait-elle pas se trouver après les boucles?
GC_

1
J'ai récemment découvert que cette technique d'étiquetage est également très utile en combinaison avec une continue LABEL;déclaration. Ainsi, vous pouvez continuer une boucle de couchage externe.
infotoni91


29

Ils pourraient donc être utilisés un jour si les concepteurs de langage en ressentaient le besoin.

De plus, si les programmeurs des langages qui ont ces mots clés (par exemple C, C ++) les utilisent par erreur, alors le compilateur Java peut donner un message d'erreur utile.

Ou peut-être que c'était juste pour arrêter les programmeurs d'utiliser goto :)


La fonctionnalité goto manquante en Java devrait être une raison suffisante pour ne pas utiliser goto - il n'est pas nécessaire de la réserver comme mot clé. Suivant votre logique, tout serait un mot-clé, car il est soit utilisé par d'autres langages et / ou les concepteurs Java POURRAIENT l'utiliser à l'avenir ...
stuXnet

1
Je ne pense pas que ma logique implique que tout serait un mot-clé. Il existe un petit ensemble de mots clés utilisés dans de nombreux langages de programmation qui peuvent être détectés et gérés de manière utile en Java. Java réservé gotoet constreflétant son héritage C / C ++ mais ils restent non implémentés (bien qu'il y ait eu des débats sur l'implémentation de ce dernier). Un couple ressemblait davantage assertet enumn'était pas initialement réservé, mais aurait peut-être dû l'être, étant donné qu'ils ont été mis en œuvre. Mais le recul est une chose merveilleuse.
dave

19

Ils sont réservés pour une utilisation future (voir: Mots clés du langage Java )

Les mots-clés const et goto sont réservés, même s'ils ne sont pas utilisés actuellement.

La raison pour laquelle il n'y a aucune instruction goto en Java peut être trouvée dans " The Java Language Environment ":

Java n'a aucune instruction goto. Des études ont montré que le goto est (mal) utilisé le plus souvent "simplement parce qu'il est là". L'élimination du goto a conduit à une simplification du langage - il n'y a pas de règles concernant les effets d'un goto au milieu d'une instruction for, par exemple. Des études sur environ 100 000 lignes de code C ont déterminé qu'environ 90% des instructions goto ont été utilisées uniquement pour obtenir l'effet de la rupture des boucles imbriquées. Comme mentionné ci-dessus, l'interruption à plusieurs niveaux et la suppression continuent de supprimer la plupart des instructions goto.


gotoest réservé, mais pas pour une utilisation future.
Marquis de Lorne

17

Un exemple d'utilisation des libellés "continuer" en Java est:

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);
    }
}

Résultats:

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

10

Il est important de comprendre que la gotoconstruction remonte à l'époque où les programmeurs programmaient en code machine et en langage assembleur. Parce que ces langues sont si fondamentaux (comme dans chaque instruction ne fait que d' une chose), le flux de contrôle du programme se fait entièrement avec des gotodéclarations (mais en langage assembleur, ceux - ci sont appelés saut ou branche instructions).

Maintenant, bien que le langage C soit de bas niveau, il peut être considéré comme un langage d'assemblage de très haut niveau - chaque instruction et fonction en C peut facilement être décomposée en instructions de langage d'assemblage. Bien que C ne soit pas le langage principal pour programmer des ordinateurs de nos jours, il est encore largement utilisé dans les applications de bas niveau, telles que les systèmes embarqués. Parce que la fonction de C reflète si étroitement la fonction du langage d'assemblage, cela n'a de sens que d' gotoêtre inclus dans C.

Il est clair que Java est une évolution de C / C ++. Java partage beaucoup de fonctionnalités de C, mais résume beaucoup plus de détails, et est donc simplement écrit différemment. Java est un langage de très haut niveau, il n'est donc tout simplement pas nécessaire d'avoir des fonctionnalités de bas niveau comme gotolorsque plus de constructions de haut niveau comme les fonctions, pour, pour chacune, et tandis que les boucles font le flux de contrôle du programme. Imaginez si vous étiez dans une fonction et que vous avez fait gotoune étiquette dans une autre fonction. Que se passerait-il lorsque l'autre fonction reviendrait? Cette idée est absurde.

Cela ne répond pas nécessairement pourquoi Java inclut l' gotoinstruction mais ne la laisse pas compiler, mais il est important de savoir pourquoi gotoa été utilisé en premier lieu, dans les applications de niveau inférieur, et pourquoi cela n'a tout simplement pas de sens d'être utilisé en Java.


msgstr "le flux de contrôle du programme se fait complètement avec goto". Eh bien, pas toujours goto inconditionnel.
Peter Mortensen

Sauter avec "goto" d'une fonction dans une étiquette dans une autre fonction n'est pas non plus possible en C / C ++. Goto en C / C ++ est limité à un seul bloc fonctionnel.
user2328447

"il n'est tout simplement pas nécessaire d'avoir des fonctionnalités de bas niveau comme goto lorsque des constructions plus de haut niveau" - rappelez-vous "Nécessité et suffisance". C'est juste "pas nécessaire". Et donc aucune raison. Ce qui EST une raison: "Goto" en tant que substitut "de haut niveau" pour les JMP, BNE et plus d'assembleur est raisonnable si vous voulez passer au "code exécutable" mais Java est un bytecode et donc pas "exécutable". ;-)
reichhart

10

Non, goton'est pas utilisé, mais vous pouvez définir des étiquettes et laisser une boucle jusqu'à l'étiquette. Vous pouvez utiliser breakou continuesuivre l'étiquette. Vous pouvez donc sauter plusieurs niveaux de boucle. Jetez un œil au tutoriel .


9

Non, heureusement, il n'y en a pas gotoen Java.

Le gotomot-clé est uniquement réservé, mais pas utilisé (il en va de même const).


Puis-je savoir ce que signifiait réservé ici? Si l'utilisation de goto et const dans le code n'est pas une bonne pratique, pourquoi le réserve-t-il? Pouvez-vous s'il vous plaît expliquer?
Gopi

@Sri Kumar: voir la réponse de @ applechewer, elle existe mais elle n'est pas implémentée.
Valentin Rocher

1
@Sri Kumar: les mots clés réservés les empêchent d'être utilisés comme noms de variables ou similaires. De cette façon, ces mots clés peuvent être implémentés dans les futures versions de Java sans casser l'ancien code source qui aurait pu autrement les utiliser.
Peter Di Cecco

8

Parce que ce n'est pas pris en charge et pourquoi voudriez-vous un gotomot clé qui n'a rien fait ou une variable nommée goto?

Bien que vous puissiez utiliser les instructions break label;et continue label;pour faire ce qui gotofonctionne efficacement . Mais je ne le recommanderais pas.

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 Pourquoi ne devrais-je pas être autorisé à avoir une variable ou une méthode nommée goto?
Michael Borgwardt

4
Parce qu'il a un sens au pays de la programmation qui n'est pas applicable à Java. C'est aussi un mauvais choix de nom de variable.
pjp

À quoi servirait une variable «impression»? Les mots que vous avez mentionnés ressemblent davantage à des noms de méthode qu'à des variables ou à des mots clés.
pjp

3
-1: Tout d'abord, juste parce que Java ne prend pas en charge l'instruction de contrôle de flux "goto", cela ne signifie pas que c'est la raison pour laquelle il a le mot-clé "goto" qui ne fait rien. Deuxièmement, "goto" peut être un mauvais nom de variable, mais il peut s'agir d'un excellent nom de méthode, que nous ne pouvons pas utiliser car "goto" est un mot clé. Troisièmement, "rompre l'étiquette" et "continuer l'étiquette" existent pour une très bonne raison, donc "ne pas le recommander" n'est pas très utile. Et quatrièmement, étant donné que Sun dit qu'il n'est "pas utilisé actuellement", cela signifie très probablement qu'ils avaient prévu de l'implémenter, mais qu'ils ne voulaient pas se débarrasser du mot-clé lorsqu'ils en avaient décidé autrement.
Vojislav Stojkovic

2
@VojislavStojkovic C'est juste un discours fou. 1) C'est la raison pour laquelle il ne fait rien est parce qu'il ne supporte pas. Selon le 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.cela signifie "Nous ne l'utilisons pas, donc si vous venez d'un arrière-plan C ++, nous ne vous laisserons pas du tout l'utiliser.". 2) gotoest un terrible nom de méthode. Désolé. 3) pause et continuer sont recommandés, mais pas de la manière utilisée ici . 4) "très probablement" [citation nécessaire].
corsiKa

7

Non, goton'est pas utilisé en Java, bien qu'il s'agisse d'un mot réservé. Il en va de même pour const. Les deux sont utilisés en C ++, ce qui est probablement la raison pour laquelle ils sont réservés; l'intention était probablement d'éviter de confondre les programmeurs C ++ migrant vers Java, et peut-être aussi de conserver la possibilité de les utiliser dans les versions ultérieures de Java.


1
J'espère vraiment que cela gotone sera pas supporté dans un avenir proche au moins;)
Bozho

6
@Bozho: eh bien, il pourrait être utilisé pour une nouvelle fonctionnalité ingénieuse qui n'a absolument rien à voir avec le mauvais vieux goto "nuisible".
Michael Borgwardt

3

Notez que vous pouvez remplacer la plupart des utilisations bénignes de goto par

  • revenir

  • Pause

  • casser l' étiquette

  • jeter à l'intérieur essayer-attraper-enfin


5
Les exceptions ne doivent JAMAIS être utilisées pour le contrôle de flux
ChssPly76

13
Des exceptions sont utilisées pour le contrôle de flux, mais ne doivent être utilisées que dans des cas exceptionnels. Par exemple, l'une des utilisations de goto en C est la gestion des erreurs, surtout si elle implique un nettoyage.
starblue

2
@starblue, vous avez sorti les mots de ma bouche. Lancer une exception est un flux de contrôle. En C, en fait, vous pouvez implémenter quelque peu proprement la gestion des exceptions via setjmp / longjmp en vous assurant d'abord de définir setjmp sur le code de gestion et en exécutant longjmp () ing sur exception.

Je veux faire une vérification if et sauter la moitié de la méthode si true. Sans aller à je dois utiliser un autre géant. OMI, c'est assez moche car trop de paranthèses créent des confusions
WVrock

1
@WVrock Vous pourriez essayerreturn
Andrew Lazarus

2

Comme cela a été souligné, il n'y gotoen a pas en Java, mais le mot-clé était réservé au cas où Sun aurait envie d'ajouter gotoJava un jour. Ils voulaient pouvoir l'ajouter sans casser trop de code, alors ils ont réservé le mot-clé. Notez qu'avec Java 5, ils ont ajouté le enummot - clé et cela n'a pas cassé autant de code non plus.

Bien que Java n'en ait pas goto, il a des constructions qui correspondent à certains usages de goto, à savoir pouvoir breaket continueavec des boucles nommées. En outre, finallypeut être considéré comme une sorte de torsion goto.


1

Interdire les déclarations de variables du même nom.

par exemple int i = 0, goto;


3
Mais pourquoi ? Pourquoi ne devrions-nous pas être autorisés à faire ces déclarations?
ApproachingDarknessFish

1

Il est très bien considéré comme l'une de ces choses que vous ne faites pas, mais a probablement été répertorié comme un mot réservé pour éviter toute confusion pour les développeurs.


1

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

Si on vous a dit qu'il n'y a aucune instruction goto en Java, vous avez été dupe. En effet, Java se compose de deux couches de code «source».


5
c'est comme dire que n'importe quel langage a un goto car il existe une branche inconditionnelle dans le code assembleur en dessous. Avoir le goto dans le code d'octet ne signifie pas qu'il y a un goto dans java car "dans java" signifie "dans le langage java", et le code d'octet n'est pas une couche de source.

@ tgm1024, "en Java" peut également être interprété comme "en plate-forme Java". Le compilateur Java doit produire un bytecode Java ou la sortie ne fonctionnera pas dans la plate-forme JVM Java. C ++, par exemple, ne spécifie pas de sortie de compilation et le compilateur est libre de produire n'importe quelle forme de code machine (ou tout autre code). L'application programmée Java bytecode peut être appelée "application Java" mais l'application programmée par code machine ne peut pas être appelée "application C ++".
Mikael Lindlöf

2
Je sais très bien ce qu'est le bytecode java. J'ai codé pour la première fois en java en 1996. Et vous pouvez avoir d'autres langages pour générer du bytecode java pour la JVM. Là où je vous corrige, c'est cette idée qu'il y a deux couches de source. Il n'y a pas. Vous avez une source java et celle-ci est compilée en code octet java (exécuté par la JVM) et ce n'est pas une couche supplémentaire de source. Ce n'est pas parce qu'il y a un "goto" dans le code d'octet qu'il y a un "goto" en java. Java a nommé des pauses et nommé continue, mais pas de goto.

@ tgm1024 J'ai été réveillé par un downvote :) Il peut facilement sembler que j'ai perdu l'argument depuis que vous avez fait le dernier commentaire et vos informations d'identification sont impressionnantes. Mon point, que je construisais, était qu'il était très possible de programmer avec du bytecode Java. Pour vous assurer, voici même une question à ce sujet: stackoverflow.com/questions/3150254/…
Mikael Lindlöf


1

Je ne suis pas fan gotonon plus, car cela rend généralement le code moins lisible. Cependant, je crois qu'il y a des exceptions à cette règle (surtout en ce qui concerne les lexers et les analyseurs!)

Bien sûr, vous pouvez toujours importer votre programme dans Kleene Normalform en le traduisant en quelque chose comme un assembleur, puis en écrivant quelque chose comme

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;
    }
}

(Donc, vous écrivez essentiellement une machine virtuelle qui exécute votre code binaire ... où linecorrespond au pointeur d'instruction)

C'est tellement plus lisible que le code qui l'utilise goto, n'est-ce pas?


Question suivante, "Existe-t-il une instruction switch en Python"
Mark K Cowan

0

Bien sûr, c'est un mot-clé, mais il n'est pas utilisé au niveau du code source.

Mais si vous utilisez jasmin ou un autre langage de niveau inférieur, qui est transformé en bytecode, alors "goto" est là


-1

Parce que bien que le langage Java ne l'utilise pas, le bytecode JVM le fait.


7
Alors pourquoi la langue n'a-t-elle pas de loadmot-clé?
ApproachingDarknessFish

3
@gribnit, avoir un goto dans le bytecode ne signifie rien en soi pour les mots réservés de niveau supérieur.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.