18
while (condition) {

    if (condition) {
        statement1;
        statement2;

        break;
    } else {
        statement3;
        statement4;
    }

}

By using break in the if clause, we ensure the loop is halted and exited.

I don't understand how the break statement "knows" that it is within a loop for it to exit out of in the first place, or how it "knows" where to jump to. How does this happen?

hexacyanide
  • 76,426
  • 29
  • 148
  • 154
UnderDog
  • 2,843
  • 10
  • 29
  • 45

5 Answers5

32

I don't understand how the break statement "knows" that it is within a loop for it to exit out of in the first place.

The break statement does not know that it's within a switch or loop statement. The compiler verifies that the break statement is within a switch or loop statement. If it encounters a break statement that is not within a loop statement, it will emit a compile-time error.

If no switch, while, do, or for statement in the immediately enclosing method, constructor, or initializer contains the break statement, a compile-time error occurs.

If the compiler is able to verify that the break statement is within a switch or loop statement, it will then emit JVM instructions to jump abruptly to the first statement immediately after the nearest enclosing loop.

Thus:

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

would be translated by the compiler into:

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
jason
  • 220,745
  • 31
  • 400
  • 507
20

break isn't your standard function. It's a keyword that's used by the Java compiler. When it sees it, it'll insert a bytecode instruction to jump to directly outside the loop, after it. This is a simple goto bytecode as shown in the answer given by Jason.

Likewise, the continue keyword effectively jumps to the beginning of the loop1.

return does this out of a function block, though with a few differences as it may need to carry a value or a reference pointing to the heap.


1 - It is actually a bit more complicated than this. Probably the best simple but accurate "model" that works for all Java loops is that continue is equivalent to jumping to an imaginary empty statement at the end of the loop body.

nanofarad
  • 36,174
  • 4
  • 79
  • 104
17

I don't understand how the break statement "knows" that it is within a loop for it to exit out of in the first place.

The compiler turns your program into a parse tree. Everything in the parse tree has a parent, except the root. The break statement must have a parent loop somewhere up the tree (or, of course, a parent switch statement).

user207421
  • 289,834
  • 37
  • 266
  • 440
  • 2
    EJP -- This an excellent line `The break statement must have a parent loop` simply shows how break implemented. a very concise and nice answer! – Grijesh Chauhan Jul 23 '13 at 07:57
  • 2
    This is the most direct answer to the question. I like the detail of the byte-code answers, but the tree the compiler builds from the code is how it knows to generate that byte-code. – Robert Fisher Jul 23 '13 at 16:05
4

If you have ever taken a look at assembly or Java byte code, this will make more sense. At a lower level, your program is compiled into "byte code" that takes advantage of registers, addresses, etc. A simple if statement can be translated into something like:

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

This might be (really bad) bytecode for:

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

Essentially, at a lower level, you use labels/line numbers and gotos to jump around the code. So a break essentially means, goto the last line of the if statement or loop.

BLaZuRE
  • 2,295
  • 2
  • 23
  • 40
4

The break statement has two forms: labeled and unlabeled.

You can use an unlabeled break to terminate a for, while, or do-while loop.

An unlabeled break statement terminates the innermost switch, for, while, or do-while statement, but a 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;
                }
            }
        }

Hope this helps.

JNL
  • 4,545
  • 13
  • 29
  • 1
    This is valid in explaining what a break does, but not how it does it at a low level, as the OP asks. – nanofarad Jul 24 '13 at 02:33
  • @hexafraction True. I answered the question yesterday and the question was edited later. I just wanted to bring into light label and unlabeled break statement too, since we had so many answers, but none had mentioned it. This would definitely help someone who is new to programming – JNL Jul 24 '13 at 02:45