18
while (condition) {

    if (condition) {
        statement1;
        statement2;

        break;
    } else {
        statement3;
        statement4;
    }

}

通过break在 if 子句中使用,我们确保循环停止并退出。

我不明白 break 语句如何“知道”它在循环中首先退出,或者它如何“知道”跳转到哪里。这是怎么发生的?

4

5 回答 5

32

我不明白 break 语句如何“知道”它在循环中首先退出。

break语句不知道它在switchor 循环语句中。编译器验证break语句是否在switchor 循环语句中。如果遇到不在break循环语句中的语句,它将发出编译时错误。

如果立即封闭的方法、构造函数或初始化程序中没有switchwhiledofor语句包含 break 语句,则会发生编译时错误。

如果编译器能够验证该break语句在switchor 循环语句中,它将发出 JVM 指令以立即跳到最近的封闭循环之后的第一条语句。

因此:

for(int i = 0; i < 10; i++) {
    if(i % 2 == 0) {
         break;
    }
}

将由编译器翻译成:

0:  iconst_0        # push integer 0 onto stack
1:  istore_1        # store top of stack in local 1 as integer                  
                    # i = 0
2:  iload_1         # push integer in local 1 onto stack
3:  bipush 10       # push integer 10 onto stack
5:  if_icmpge 23    # pop and compare top two (as integers), jump if first >= second
                    # if i >= 10, end for
8:  iload_1         # push integer in local 1 onto stack
9:  iconst_2        # push integer 2 onto stack
10: irem            # pop top two and computes first % second and pushes result
                    # i % 2
11: ifne 17         # pop top (as integer) and jump if not zero to 17
                    # if(i % 2 == 0) 
14: goto 23         # this is the break statement
17: iinc 1, 1       # increment local 1 by 1
                    # i++
20: goto 2          # go to top of loop
                    # loop
23: return          # end of loop body
于 2013-07-23T02:39:24.627 回答
20

break不是您的标准功能。它是 Java 编译器使用的关键字。当它看到它时,它会在它之后插入一个字节码指令直接跳转到循环之外。这是一个简单的 goto 字节码,如 Jason 给出的答案所示。

同样,continue关键字有效地跳转到循环1的开头。

return在功能块之外执行此操作,尽管有一些差异,因为它可能需要携带一个值或指向堆的引用。


1 - 它实际上比这更复杂一些。可能适用于所有 Java 循环的最简单但准确的“模型”continue相当于在循环体的末尾跳转到一个虚构的空语句。

于 2013-07-23T02:02:00.883 回答
17

我不明白 break 语句如何“知道”它在循环中首先退出。

编译器将您的程序变成解析树。解析树中的所有内容都有一个父节点,除了根节点。break 语句必须在树的某处有一个父循环(或者,当然,一个父 switch 语句)。

于 2013-07-23T02:13:27.020 回答
4

如果您曾经看过汇编或 Java 字节码,这将更有意义。在较低级别,您的程序被编译为利用寄存器、地址等的“字节码”。一个简单的 if 语句可以翻译成如下内容:

3: if_icmpeq 5
4: goto 10
5: iconst_1
6: iload_1
7: iconst_2
8: iload_2
9: if_icmpeq 10
10: // end of if-else statement

这可能是(非常糟糕的)字节码:

if ( x == y )
  if ( 1 == 2 )

本质上,在较低级别,您使用标签/行号和 goto 来跳转代码。因此,abreak本质上意味着,转到 if 语句或循环的最后一行。

于 2013-07-23T02:21:32.373 回答
4

break 语句有两种形式:有标签的和无标签的。

您可以使用未标记的中断来终止for, while, or do-while loop.

一个未标记的 break 语句终止innermost switch, for, while, or do-while statement,但是一个labeled break terminates an outer statement.

   search:
        for (i = 0; i < arrayOfInts.length; i++) {
            for (j = 0; j < arrayOfInts[i].length;
                 j++) {
                if (arrayOfInts[i][j] == 5) {
                    foundIt = true;
                    break search;
                }
            }
        }

希望这可以帮助。

于 2013-07-23T02:32:49.517 回答