【问题标题】:Labeled break just after loop not working in Java循环后标记的中断在Java中不起作用
【发布时间】:2020-01-25 04:09:25
【问题描述】:
for(int x = 0; x < 5; x++)
        stop2: {
                System.out.println("Count");
                if (x == 2)
                    break stop2;
        }

        stop3: for(int x = 0; x < 5; x++) {
                System.out.println("Second");
                if (x == 2)
                    break stop3;
        } 

在学习 Java 中的标记中断时,我注意到将标签放在 for 语句之前和之后会产生不同的结果。在上面的代码中,带有 stop2 的 for 循环在打印“Count” 3 次后并没有停止,而另一个则停止了。有人可以解释这两者之间的区别吗?我认为标记的 break 会在标签之后立即破坏身体......

【问题讨论】:

  • 第一个例子是不合法的。我很惊讶它可以编译。
  • @user207421 - 试试看......并检查我的答案中的 JLS 链接。

标签: java for-loop break labeled-statements


【解决方案1】:

在第一个示例中,您的语法不正确(对于您想要的行为)。这个

for(int x = 0; x < 5; x++)
stop2: {
    System.out.println("Count");
    if (x == 2)
        break stop2;
}

应该是

stop2: for (int x = 0; x < 5; x++) {
    System.out.println("Count");
    if (x == 2) {
        break stop2;
    }
}

只是

for (int x = 0; x < 5; x++) {
    System.out.println("Count");
    if (x == 2) {
        break;
    }
}

因为当没有标签应用于break 时,未标记的break 应用于第一个(即最里面的)循环。

【讨论】:

  • '没有标签'应该从这里删除。
  • @user207421 怎么样? break 没有标签,意味着循环也不需要标签。
  • 您的意思是,如果循环有标签,则在查找最里面时不会考虑它。我敢肯定你不是那个意思。
【解决方案2】:

我认为标记的 break 会在标签之后立即破坏身体。

没有。它破坏了标签所附的语句(或块)。

因此:

  for (int x = 0; x < 5; x++)
      stop2: {
            // stuff
            break stop2;
      }

打破了for循环的主体语句,但是

 stop3: for (int x = 0; x < 5; x++)
      {
          //stuff
          break stop3;
      }

破坏for 语句。

对比一下

for (int x = 0; x < 5; x++)
      {
          //stuff
          break;
      }

一个普通的(无标签的)break 只能用在循环或 switch 语句中,它会破坏立即封闭的循环或 switch。

JLS 14.15 是这么说的:

"没有标签的break 语句试图将控制转移到最里面的封闭方法或初始化程序的switchwhiledofor 语句;此语句是调用中断目标,然后立即正常完成。”

“带有标签Identifierbreak 语句尝试将控制权转移到具有相同标签Identifier 的封闭标签语句(第14.7 节);该语句称为break 目标,然后立即正常完成。在这种情况下,中断目标不必是switchwhiledofor 语句。"

因此,确定break 语句(普通或标记)的作用的关键是中断目标是什么。


这有点晦涩难懂……也是仅在绝对必要时才使用带标签语句的另一个好理由。我看不出在您的示例中使用它们的理由(插图除外)。其中一个应该写成普通的break,另一个应该写成continue

但是(对于怀疑者)这两个示例都是有效的、可编译的 Java 代码,并且根据 JLS 都具有明确定义的含义。

【讨论】:

  • 谢谢,这个例子只是一个插图。
【解决方案3】:
      for(int x = 0; x < 5; x++)
        stop2: {
                System.out.println("Count");
                if (x == 2)
                    break stop2;
        }

在这种情况下,当您中断标签 stop2 时,控件会再次返回到 for 循环并开始下一次迭代 (x = 3)。

        stop3: for(int x = 0; x < 5; x++) {
                System.out.println("Second");
                if (x == 2)
                    break stop3;
        } 

在情况 2 中,当您中断标签 stop3 时,控件不会再次返回到 for 循环。

【讨论】:

    【解决方案4】:

    在您的情况下,您不需要标记中断。 在 Java 中,break 语句会中断包含它的循环。 所以你的stop2 代码块真的可以。

    for (int x = 0; x < 5; x++) {
        System.out.println("Count");
        if (x == 2) {
            break stop2;
        }
    }
    

    标记中断的一个例子就是这样。

    假设您在循环中有一个循环,并且在某些情况下您想跳出外循环。 示例:

    stop2:
    for (int x=0; x < 5; x++) {
      for (int y=0; y<5;y++) {
        if (x == 3 && y == 2)  { //just making up some condition for the example
            break stop2;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-25
      • 2013-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多