Java中goto关键字的替代功能是什么?
由于Java没有goto。
Java中goto关键字的替代功能是什么?
由于Java没有goto。
Answers:
您可以使用带标签的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功能。
goto
Java中没有直接等效的概念。有几种结构可以让您完成经典型可以做的一些事情goto
。
break
和continue
语句,可以在循环或switch语句跳跃块了。break <label>
允许您从任意复合语句跳到给定方法(或初始化程序块)内的任何级别。continue <label>
从内部循环继续进行外部循环的下一次迭代。return
。这些Java构造均不允许您在与当前语句相同的嵌套级别上向后或分支到代码中的某个点。它们都跳出一个或多个嵌套(作用域)级别,并且所有(除之外continue
)都向下跳。此限制有助于避免旧的BASIC,FORTRAN和COBOL代码2固有的goto“意大利面条代码”综合症。
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。应该为> =
尽管一些评论者和反对者认为这不是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 ..
continue label
是倒退吗
// do stuff
和// do more stuff
是感兴趣的陈述,则continue label
“具有效果”向后跳(while(true)
当然是由于陈述)。我不知道这是一个如此精确的问题,但是……
while(true)
是由编译器为翻译后goto
的字节码操作。作为true
常量常量,编译器可以执行此优化,而不必评估任何内容。所以,我的例子确实是一个goto,向后跳……
如果您确实想要诸如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可以执行的一些操作。
多一个...
马特·沃尔夫写道:
人们总是谈论从未使用过goto,但是我认为有一个非常好的现实世界用例,它非常众所周知并已被使用。也就是说,确保在从函数返回之前执行一些代码。通常会释放它。锁定或不锁定,但就我而言,我希望能够在返回之前跳到一个中断,这样我可以执行必需的强制清理。
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
try块退出时,finally块始终执行。这样可以确保即使发生意外异常,也可以执行finally块。但是,最后,它不仅对异常处理有用,它还使程序员避免因返回,继续或中断而意外跳过清理代码。将清理代码放在finally块中始终是一个好习惯,即使没有预期例外的情况。
与final相关的愚蠢面试问题是:如果您从try {}块返回,但您的finally {}也有返回,则返回哪个值?
return
放在一个finally
块中也是一个坏主意。(即使知识不是绝对必要的,我也会因为没有好奇心的程序员而担心...)
试试下面的代码。这个对我有用。
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++) {"
Java没有goto
,因为它使代码非结构化和不清晰阅读。但是,您可以使用goto并将其作为文明形式使用break
,不会出现任何问题。continue
ahead: {
System.out.println("Before break");
break ahead;
System.out.println("After Break"); // This won't execute
}
// After a line break ahead, the code flow starts from here, after the ahead block
System.out.println("After ahead");
输出:
Before Break
After ahead
before: {
System.out.println("Continue");
continue before;
}
这将导致无限循环,因为每次continue before
执行该行时,代码流都会从重新开始before
。
goto
能在Java中使用,您可以举一个您将编写的代码类型的例子吗?我认为其中存在着更重要的问题。