18
while (condition) {

    if (condition) {
        statement1;
        statement2;

        break;
    } else {
        statement3;
        statement4;
    }

}

breakif 句で使用することにより、ループが停止して終了することを保証します。

break ステートメントがループ内にあることを最初に「認識」する方法、またはどこにジャンプするかを「認識する」方法がわかりません。これはどのように起こりますか?

4

5 に答える 5

32

そもそも break ステートメントがループ内にあることを「認識」する方法がわかりません。

ステートメントは、or ループ ステートメントbreak内にあることを認識していません。switchコンパイラは、ステートメントがor ループ ステートメント内にあることを確認します。ループ ステートメント内にないステートメントに遭遇すると、コンパイル時エラーが発生します。breakswitchbreak

すぐ外側のメソッド、コンストラクター、または初期化子のswitchwhiledo、またはforステートメントに break ステートメントが含まれていない場合、コンパイル時エラーが発生します。

breakステートメントが or ループ ステートメント内にあることをコンパイラが確認できる場合、コンパイラはswitchJVM 命令を発行して、最も近い外側のループの直後の最初のステートメントに突然ジャンプします。

したがって:

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 コンパイラで使用されるキーワードです。それを見ると、ループのすぐ外側にジャンプするバイトコード命令を挿入します。これは、Jason の回答に示されている単純な goto バイトコードです。

同様に、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 を使用してコードをジャンプします。したがって、break本質的には、if ステートメントまたはループの最後の行に移動することを意味します。

于 2013-07-23T02:21:32.373 に答える
4

break ステートメントには、labeled と unlabeledの 2 つの形式があります。

ラベルのないブレークを使用して、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 に答える