goto关键字在Java中没有对应的替代函数。
goto关键字在Java中没有对应的替代函数。
您可以使用带标签的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;
}
}
}
然而,在设计良好的代码中,你不应该需要使用GOTO功能。
Java中没有与goto
概念直接等价的语法。有一些结构可以让你做一些你可以用传统的goto
来做的事情。
break
和continue
语句允许你跳出循环或switch语句中的块。break <label>
允许你跳出任意复合语句并到达给定方法(或初始化程序块)内的任何级别。continue <label>
从内部循环继续进行外部循环的下一次迭代。return
语句。以上这些Java结构都不允许你向后或者向当前语句嵌套级别相同的代码点进行跳转。它们都跳出一层或多层嵌套(作用域)并且它们都(除了continue
)是向下跳转的。这种限制有助于避免旧的BASIC、FORTRAN和COBOL代码中的goto“意大利面条”式编程综合症2。
1- 异常的最昂贵的部分是实际创建异常对象及其堆栈跟踪的过程。如果你真的需要使用异常处理来进行“正常”的控制流,你可以预先分配/重用异常对象,或者创建一个自定义异常类,覆盖fillInStackTrace()
方法。缺点是异常的printStackTrace()
方法将无法提供有用的信息...如果你需要调用它们。
2- 意大利面条式编程出现后,引发了 结构化编程 方法,您需要限制使用可用的语言结构。它可以应用于 BASIC、Fortran 和 COBOL,但需要谨慎和纪律。完全摆脱 goto
是一个更为实际的解决方案。如果在语言中保留它,总会有一些小丑会滥用它。
仅供娱乐,这里提供了Java中的GOTO实现。
示例:
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 }
运行它:
我需要添加“不要使用它!”吗?$ java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo 3 2 1 0 Hello World!
Math.random()
可能会返回 0。它应该是 >= 0。 - poitroaeHellWorld!o World!
时会感到困惑。#所有的错误都是特性 - ReinstateMonica3167040虽然一些评论者和投票者认为这不是 goto,但下面的Java语句生成的字节码确实表明这些语句确实表达了 goto 语义。
具体来说,第二个示例中的 do {...} while(true);
循环被 Java 编译器优化,以便不评估循环条件。
label: {
// do stuff
if (check) break label;
// do more stuff
}
以字节码形式:
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);
字节码中:
2 iload_1 [check]
3 ifeq 9
6 goto 2 // Jumping backward
9 ..
while(true)
被编译器转换为goto
字节码操作。由于true
是一个常量字面量,编译器可以进行这种优化,而不必评估任何内容。因此,我的示例实际上是一个向后跳转的goto
。 - Lukas Ederdo
while
创建了一个新的作用域,但我们可以将声明放在它的外面。 - Ciro Santilli OurBigBook.com如果你真的想要类似于 goto 语句的东西,你总是可以尝试跳转到具有名称的块。
你必须在该块的范围内才能跳转到该标签:
namedBlock: {
if (j==2) {
// this will take you to the label above
break namedBlock;
}
}
我不会在这里向你讲授为什么应该避免使用goto语句 - 我假设你已经知道了答案。
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写道:
有两个结构可以让你做一些使用经典goto的事情。
还有一个...
Matt Wolfe写道:
人们总是谈论永远不要使用goto,但我认为有一个非常好的现实用例是相当出名和常用的。也就是确保在从函数返回之前执行一些代码。通常是释放锁或其他操作,但在我的情况下,我希望能够在返回之前跳转到break,以便我可以进行必需的强制清理。
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
finally块总是在try块退出时执行。这确保了即使出现意外异常,也会执行finally块。但finally不仅用于异常处理 - 它允许程序员避免清理代码被返回、继续或中断绕过的情况。将清理代码放在finally块中始终是一个好习惯,即使不预期发生任何异常也是如此。 与finally相关的一个愚蠢的面试问题是:如果你从try{}块返回,但是在finally{}中也有一个return,那么返回哪个值?finally
块中放置return
是个坏主意的原因。即使这个知识并不是严格必要的,但如果一个程序员没有好奇心去了解,我也会感到担忧... - Stephen C。
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;
}
}
for (String label = "start";;) {
switch (label) {
case "start":
...
case "something":
...
case "whatever":
...
label = "something"; break; // <== those two commands equal goto
...
default:
return;
}
}
尝试下面的代码。它对我有效。
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++) {"