Qu'est-ce qu'une fonction alternative pour le mot clé goto en Java?
Depuis Java n'a pas de goto.
Vous pouvez utiliser une instruction BREAK :
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length; j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
Cependant, dans un code correctement conçu, vous ne devriez pas avoir besoin de la fonctionnalité GOTO.
Il n'y a pas d'équivalent direct au concept goto
en Java. Il y a quelques constructions qui vous permettent de faire certaines choses que vous pouvez faire avec un goto
classique.
break
et continue
vous permettent de sortir d'un bloc dans une instruction loop ou switch.break <label>
Vous permettent de sortir d'une instruction composée arbitraire vers n'importe quel niveau d'une méthode donnée (ou d'un bloc d'initialisation).continue <label>
Pour continuer avec la prochaine itération d'une boucle externe à partir d'une boucle interne.return
.Aucune de ces constructions Java) ne vous permet de basculer en arrière ou vers un point du code au même niveau d’imbrication que l’instruction en cours. Toutes dépassent un ou plusieurs niveaux d’imbrication (portée) et tous (sauf continue
) sautent vers le bas. Cette restriction permet d'éviter le syndrome de goto "code spaghetti" inhérent aux anciens codes BASIC, FORTRAN et COBOL.2.
1- La partie la plus chère des exceptions est la création réelle de l'objet exception et de son stacktrace. Si vous devez réellement utiliser la gestion des exceptions pour un contrôle de flux "normal", vous pouvez soit pré-allouer/réutiliser l'objet exception, soit créer une classe d'exception personnalisée qui remplace la méthode fillInStackTrace()
. L'inconvénient est que les méthodes printStackTrace()
de l'exception ne vous donneront pas d'informations utiles ... si jamais vous deviez les appeler.
2 - Le syndrome du code spaghetti a engendré l'approche programmation structurée , dans laquelle vous avez limité votre utilisation des constructions de langage disponibles. Ceci pourrait être appliqué à DE BASE , Fortran et COBOL =, mais cela demandait soin et discipline. Se débarrasser entièrement de goto
était une meilleure solution pragmatique. Si vous le gardez dans une langue, il y a toujours un clown qui en abusera.
Juste pour le plaisir, ici est une implémentation de GOTO en Java.
Exemple:
1 public class GotoDemo { 2 public static void main(String[] args) { 3 int i = 3; 4 System.out.println(i); 5 i = i - 1; 6 if (i >= 0) { 7 GotoFactory.getSharedInstance().getGoto().go(4); 8 } 9 10 try { 11 System.out.print("Hell"); 12 if (Math.random() > 0) throw new Exception(); 13 System.out.println("World!"); 14 } catch (Exception e) { 15 System.out.print("o "); 16 GotoFactory.getSharedInstance().getGoto().go(13); 17 } 18 } 19 }
Le lancer:
$ Java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo 3 2 1 0 Hello World!
Dois-je ajouter "ne l'utilisez pas!"?
Alors que certains commentateurs et votants votants affirment que ce n'est pas goto, le bytecode généré à partir du code ci-dessous Java énonce vraiment que ces énoncés expriment vraiment goto sémantique.
Plus précisément, la boucle do {...} while(true);
du deuxième exemple est optimisée par les compilateurs Java) afin de ne pas évaluer la condition de la boucle.
label: {
// do stuff
if (check) break label;
// do more stuff
}
En bytecode:
2 iload_1 [check]
3 ifeq 6 // Jumping forward
6 ..
label: do {
// do stuff
if (check) continue label;
// do more stuff
break label;
} while(true);
En bytecode:
2 iload_1 [check]
3 ifeq 9
6 goto 2 // Jumping backward
9 ..
Si vous voulez vraiment quelque chose comme des instructions goto, vous pouvez toujours essayer de casser des blocs nommés.
Vous devez être dans la portée du bloc pour vous briser l'étiquette:
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
Je ne vous expliquerai pas pourquoi vous devriez éviter les goto - je suppose que vous connaissez déjà la réponse à cette question.
public class TestLabel {
enum Label{LABEL1, LABEL2, LABEL3, LABEL4}
/**
* @param args
*/
public static void main(String[] args) {
Label label = Label.LABEL1;
while(true) {
switch(label){
case LABEL1:
print(label);
case LABEL2:
print(label);
label = Label.LABEL4;
continue;
case LABEL3:
print(label);
label = Label.LABEL1;
break;
case LABEL4:
print(label);
label = Label.LABEL3;
continue;
}
break;
}
}
public final static void print(Label label){
System.out.println(label);
}
StephenC écrit:
Deux concepts vous permettent de faire certaines des choses que vous pouvez faire avec un goto classique.
Un de plus...
Matt Wolfe écrit:
Les gens parlent toujours de ne jamais utiliser un goto, mais je pense qu'il existe un très bon cas d'utilisation dans le monde réel, qui est assez bien connu et utilisé. serrures ou quoi, mais dans mon cas, j'aimerais pouvoir faire une pause juste avant le retour afin que je puisse effectuer le nettoyage obligatoire obligatoire.
try {
// do stuff
return result; // or break, etc.
}
finally {
// clean up before actually returning, even though the order looks wrong.
}
http://docs.Oracle.com/javase/tutorial/essential/exceptions/finally.html
Le bloc finally s'exécute toujours à la sortie du bloc try. Cela garantit que le bloc finally est exécuté même si une exception inattendue se produit. Mais finalement, c'est utile pour plus que la gestion des exceptions - cela permet au programmeur d'éviter que le code de nettoyage soit contourné accidentellement par un retour, une poursuite ou une interruption. Mettre le code de nettoyage dans un bloc finally est toujours une bonne pratique, même si aucune exception n'est anticipée.
La question idiote de l'entrevue associée à finally est la suivante: Si vous revenez d'un bloc try {}, mais que vous avez également un retour dans votre} {}, quelle valeur est renvoyée?
Le plus simple est:
int label = 0;
loop:while(true) {
switch(state) {
case 0:
// Some code
state = 5;
break;
case 2:
// Some code
state = 4;
break;
...
default:
break loop;
}
}
Essayez le code ci-dessous. Ça marche pour moi.
for (int iTaksa = 1; iTaksa <=8; iTaksa++) { // 'Count 8 Loop is 8 Taksa
strTaksaStringStar[iCountTaksa] = strTaksaStringCount[iTaksa];
LabelEndTaksa_Exit : {
if (iCountTaksa == 1) { //If count is 6 then next it's 2
iCountTaksa = 2;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 2) { //If count is 2 then next it's 3
iCountTaksa = 3;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 3) { //If count is 3 then next it's 4
iCountTaksa = 4;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 4) { //If count is 4 then next it's 7
iCountTaksa = 7;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 7) { //If count is 7 then next it's 5
iCountTaksa = 5;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 5) { //If count is 5 then next it's 8
iCountTaksa = 8;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 8) { //If count is 8 then next it's 6
iCountTaksa = 6;
break LabelEndTaksa_Exit;
}
if (iCountTaksa == 6) { //If count is 6 then loop 1 as 1 2 3 4 7 5 8 6 --> 1
iCountTaksa = 1;
break LabelEndTaksa_Exit;
}
} //LabelEndTaksa_Exit : {
} // "for (int iTaksa = 1; iTaksa <=8; iTaksa++) {"