Java代码中的“循环:”。这是什么,为什么会编译?


113

这段代码使我凝视了几分钟:

loop:
for (;;) {
    // ...
}

这里的第137行

我以前从未见过,而且我也不知道Java有一个“ loop”关键字(NetBeans甚至没有像关键字一样给它上色),并且它在JDK 6中可以很好地编译。

有什么解释?

Answers:


205

它不是一个keyword,而是一个label

用法:

    label1:
    for (; ; ) {
        label2:
        for (; ; ) {
            if (condition1) {
                // break outer loop
                break label1;
            }
            if (condition2) {
                // break inner loop
                break label2;
            }
            if (condition3) {
                // break inner loop
                break;
            }
        }
    }

文件资料


19
值得一提的是,由于OP可能不熟悉goto / label概念,因此在非常特殊的情况下(例如,用于简化多个嵌套循环),通常将其视为一种不好的做法。
haylem 2010年

10
@haylem正确,但我会做得更进一步:多个嵌套循环通常也是不好的做法。每当使用循环标签时,我最终都会重构代码,因此不需要它们。总有比这更好的方法。
肖恩·帕特里克·弗洛伊德

73

正如其他张贴者所说,这是一个标签,而不是关键字。使用标签可以执行以下操作:

outer: for(;;) {
   inner: for(;;) {
     break outer;
   }
}

这允许打破外环。

链接到文档


31

该问题已得到回答,但请注意:

我听说过面试问题“为什么这个Java代码有效?” (摘录了更简单的示例;这是卑鄙的人,蒂姆·布特(TimBüthe)):

url: http://www.myserver.com/myfile.mp3
downLoad(url);

你们都知道这段代码是什么(除了糟糕的)?

解决方案:两个标签,urlhttp,注释www.myserver.com/myfile.mp3和带有与url标签同名()的参数的方法调用。是的,这会编译(如果您在其他地方定义了方法调用和局部变量)。


仅供参考,您不需要循环;在下一行就足够了
TimBüthe10年

感谢您提醒我,我认为问题没有循环。我将编辑答案(从未有人问我这个问题,但面试官是我的前同事)
肖恩·帕特里克·弗洛伊德

16

那不是关键字,而是标签。它应与嵌套循环内的breakand continue关键字一起使用:

outer:
for(;;){
    inner:
    for(;;){
        if(){
            break inner; // ends inner loop
        } else {
            break outer; // ends outer loop
        }
    }
}

inner标签在这里没用,break;就足够了
gertas,2010年

12
如果有两种方法可以打破循环,我感谢您inner提供清晰的标签。
史蒂夫·杰克逊

1
@ Gertas:我认为他只是在说明这一点。但是根据史蒂夫·杰克逊(Steve Jackson)的说法,无论如何,出于自我记录目的而说它可能是一个好主意。
杰伊

5

这不是关键字;这是一个标签

它使您可以去标记break和标记continue


4

这实际上是对seanizer对org.life.java的回答的评论的答复,但是我想输入一些代码,因此无法使用评论功能。

虽然很少能找到“中断标签”的用法,但它确实偶尔发生。最常见的情况是,当我搜索的结构中需要嵌套循环进行搜索时,例如:

search:
for (State state : stateList)
{
  for (City city : state.cityList)
  {
    if (city.zipcode.equals(wantZip))
    {
      doSomethingTo(city);
      break search;
    }
  }
}

通常,在这种情况下,我会将整个东西压入一个子例程中,这样一经命中,我就可以返回找到的对象,如果它掉入了循环的底部,我可以返回null表示未找到,或者抛出异常。但这偶尔有用。

坦率地说,我认为Java的发明者包括了此功能,因为在此处理与异常处理之间,他们消除了GOTO的最后两个合法用途。

附录很晚:

我曾经看过一段很棒的代码行。程序员写道:

http://www.example.com/xyz.jsp
for (Foo foo1 : foolist)

他实际上不是说“ example.com”,而是说我们公司的网站。

它给人的感觉是代码中有一个URL。它可以成功编译,就像执行某些操作一样。但是...它是做什么的?

实际上,它什么也不做。“ http:”是他从未引用过的标签。然后,“ //”使该行的其余部分成为注释。






1

它不是关键字,而是标签。如果在for循环中,则编写break loop;,然后退出该循环。


0

它是一个标签。通常,Java中使用的标签将控制流转移到所需的位置,而所有关键字(例如continue和break)都有指定的位置选择。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.