There are however, two control flow statements that allow you to change the control flow.
The enclosing loop of a statement is the loop (or loops) in which a statement is in its loop body.
For example:
while ( j < k ) // LOOP 1 { j++ ; } while ( i < 0 ) // LOOP 2 { statement ; } do // LOOP 3 { j++ ; } while ( j < k ) ;The enclosing loop of statement is LOOP 2. That's because it's in LOOP 2's loop body. Neither LOOP 1 nor LOOP 3 are the enclosing loop for statement.
Here's the simple test:
If statement appears in the loop body of LOOP. Then, LOOP is an enclosing loop of statement.statement can have more than one enclosing loops.
while ( i < 0 ) // LOOP 1 { while ( j < k ) // LOOP 2 { statement ; j++ ; } }In this example, statement has two enclosing loops. It's in the loop body of LOOP 1 andLOOP 2, so both LOOP 1 and LOOP 2 are the enclosing loops of statement.
If a statement has more than one enclosing loop, then these enclosing loops must be nested in one another. This makes sense, if you think about it.
If we make a small change to the code:
while ( i < 0 ) // LOOP 1 { statement ; while ( j < k ) // LOOP 2 { j++ ; } }The enclosing loop for statement is just LOOP 1. LOOP 2 is no longer an enclosing loop because we're not in the loop body of LOOP 2, as in the previous example.
We use enclosing loops to explain how break and continue work.
while ( i < 0 ) // LOOP 1 { while ( j < k ) // LOOP 2 { statement ; j++ ; } }The innermost enclosing loop of statement is LOOP 2. LOOP 1 is an enclosing loop as well, but it's not the innermost enclosing loop.
Here's another example:
while ( i < 0 ) // LOOP 1 { statement ; while ( j < k ) // LOOP 2 { j++ ; } }In this example, the innermost enclosing loop of statement is LOOP 1. It isn't LOOP 2 because LOOP 2 is not even an enclosing loop of statement!
We say innermost enclosing loop, even if there is only one enclosing loop. In that case, the only enclosing loop is the innermost enclosing loop.
I know we've spent a great deal of time explaining this concept, but it should make it easier for you to follow the rest of the explanation.
Notice each statement may have a different enclosing loop.
public void twoNum( int num, int val ) { for ( int i = 0 ; i < num ; i++ ) { if ( num >= 2 * val ) break ; val = val / 2 ; } // break comes here if it runs }A break statement, if executed, jumps out of the innermost enclosing loop of the statement.
In general, you can only break out of a single loop (namely, the innermost enclosing loop of the break statement). For example
public void twoNum( int num, int val ) { for ( int i = 0 ; i < num ; i++ ) { for ( int j = 0 ; j < num ; j++ ) { if ( i + j >= 2 * val ) break ; val = val / 2 ; } // break comes here if it runs } }Java has made break more powerful. Sometimes you want to break out of more than one loop.
public void twoNum( int num, int val ) { OUTER_LOOP: // OUTER_LOOP is a label for ( int i = 0 ; i < num ; i++ ) { for ( int j = 0 ; j < num ; j++ ) { if ( i + j >= 2 * val ) break OUTER_LOOP ; val = val / 2 ; } } // break comes here if it runs }OUTER_LOOP is a label that's placed just before a loop.
When you write:
break OUTER_LOOP ;the label, OUTER_LOOP, must be a label for an enclosing loop. Usually, this is not the innermost enclosing loop since we can just use a plain break statement, instead of a "break with a label".
The label must be before a enclosing loop of the break statement.
The following is illegal
public void twoNum( int num, int val ) { LOOP: for ( int i = 0 ; i < num ; i++ ) { sum += i ; } for ( int j = 0 ; j < num ; j++ ) { if ( i + j >= 2 * val ) break LOOP ; // ILLEGAL. LOOP not an enclosing loop val = val / 2 ; } }This is illegal. The label LOOP labels a for loop. But this loop is not an enclosing loop for the statement, break LOOP. You can't break out of a loop that's not enclosing the break statement.
If a break statement appears in an if body, just ignore the if. Find the innermost enclosing loop or innermost switch statement. Pick the innermost of the two, and then exit out of the loop or switch statement, whichever is innermost.
A break statement must appear in a loop body or a body of a switch statement, otherwise the code won't compile.
If the innermost enclosing loop of a continue statement is a while or do-while loop, then running a continue statement causes control flow to jump to the cond of the innermost enclosing loop. If the innermost enclosing loop is a for loop, continue jumps to the update of that loop.
The continue statement causes control flow to go to the next iteration of the loop, skipping over the remainder of the loop body.
Consider this example:
while ( i != 3 ) // continue jumps here { if ( i > num ) continue ; // Jumps to condition, i != 3 System.out.println( "Here I am!" ) ; }If the continue statement runs, then it causes control flow to jump to the condition of the enclosing while loop.
In a for loop, it jumps to the update.
for ( i = 0 ; i < num ; i++ ) { if ( i > num / 2 ) continue ; // Jumps to update, i++ System.out.println( "Here I am!" ) ; }
If the label appears before a while loop or a do while, then "continue with a label" jumps to the cond of the loop with the label.
If the label appears before a for loop, then it jumps to the update of that loop. As with "break with a label", "continue with a label" must have a label on an enclosing loop.
while ( true ) // Intentional infinite loop { // CODE break ; // MORE CODE }Writing conditions for a loop is tough. So, some beginners avoid writing conditions by using true for the condition. This causes an infinite loop. With break, infinite loops are no longer a problem. You use break to get out of the loop.
But it makes it more difficult to see when you exit a loop. As a programmer, you need to learn how to write loop conditions. By using break, there's a temptation not to learn it.
Later on, when you've mastered writing loop conditions and when you've seen break statements used by expert coders, then you can use break the way it's meant to be used.
In the meanwhile, avoid using break and continue, but understand how it works anyway.