Java如何知道在中断循环时跳到哪里?

2022-09-02 14:17:11
while (condition) {

    if (condition) {
        statement1;
        statement2;

        break;
    } else {
        statement3;
        statement4;
    }

}

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

我不明白 break 语句如何“知道”它位于一个循环中,以便它首先退出,或者它如何“知道”跳到哪里。这是如何发生的?


答案 1

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

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

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

如果编译器能够验证该语句是否在 or 循环语句中,那么它将发出 JVM 指令,以在最近的封闭循环之后立即突然跳转到第一个语句。breakswitch

因此:

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

答案 2

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

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

return从功能块中执行此操作,但有一些区别,因为它可能需要携带指向堆的值或引用。


1 - 它实际上比这更复杂。也许适用于所有Java循环的最好简单但准确的“模型”是,continue相当于跳转到循环体末尾的虚构语句。


推荐