2.4 Loops and Branching Statements
Key Takeaways
- while loops evaluate termination conditions at loop entry, whereas do-while loops evaluate conditions at exit, guaranteeing at least one body execution.
- Classic for loop headers allow multiple comma-separated initializations of the same type and multiple comma-separated update statements.
- The enhanced for-each loop iterates over arrays and Iterable objects but forbids structural modification of collections during traversal.
- Labeled break and continue statements permit precise transfer of control across nested loops and labeled statement blocks.
Looping Statements and Branching Constructs
Iteration and jumping control constructs allow Java programs to execute code repeatedly and alter execution flow. For the Oracle Certified Professional: Java SE 21 Developer (1Z0-830) exam, candidates must master the precise semantics of all four loop types (while, do-while, traditional for, and enhanced for-each), labeled break and continue statements, and Java's rigorous compile-time reachability rules.
1. The Four Looping Constructs
The while Loop
A while loop evaluates its boolean condition prior to executing the loop body:
while (booleanExpression) { statement; }
- If the condition is initially
false, the body executes zero times. - Reachability Rule: If the condition is the literal
false, the compiler flags the body as unreachable code and generates a compile-time error:// while (false) { System.out.println("Unreachable"); } // COMPILE ERROR! Unreachable code boolean flag = false; while (flag) { System.out.println("Reachable compile-time check"); } // Compiles cleanly!
The do-while Loop
A do-while loop executes its body first, then evaluates the condition at the end of each iteration:
do { statement; } while (booleanExpression);
- Guarantees at least one execution of the loop body.
- Note the required trailing semicolon
;afterwhile(condition);. - Variable Scope in Condition: Variables declared inside the
doblock are out of scope in thewhileconditional check:do { int counter = 1; System.out.println(counter); } while (counter < 5); // COMPILE ERROR: cannot find symbol 'counter'
2. Classic for Loops and Enhanced for-each
Classic for Loop Anatomy
A classic for loop contains three header sections separated by semicolons:
for (initialization; condition; update) { statement; }
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println(i + " " + j);
}
- Initialization Section Rules:
- You can declare multiple variables, but they must share the same data type:
for (int i = 0, j = 10; i < 5; i++) {} // Legal: both are int // for (int i = 0, long j = 10; i < 5; i++) {} // COMPILE ERROR: multiple type declarations - If variables are declared prior to the loop, you can initialize variables of different types using comma-separated assignment expressions:
int i; long j; for (i = 0, j = 10L; i < 5; i++) {} // Legal assignment expressions!
- You can declare multiple variables, but they must share the same data type:
- Termination Condition Section Rules:
- Must evaluate to a
booleanorBoolean. - Optional: If omitted, it defaults to
true(creating an infinite loop:for (;;) {}).
- Must evaluate to a
- Update Section Rules:
- Can contain zero or more comma-separated expression statements (e.g.,
i++, j--, method invocations). - Side effects inside update expressions take place at the end of each iteration before the next condition check.
- Can contain zero or more comma-separated expression statements (e.g.,
Enhanced for-each Loop
The enhanced for loop provides clean, read-oriented traversal over arrays and objects implementing java.lang.Iterable<T> (such as List, Set, Queue):
for (ElementType variable : expression) { statement; }
String[] fruits = {"Apple", "Banana", "Cherry"};
for (String fruit : fruits) {
System.out.println(fruit);
}
Enhanced for-each Compilation & Traps:
- Target Type Compatibility: The target expression must evaluate to an array or a type implementing
java.lang.Iterable<T>. Passing ajava.util.Mapdirectly causes a compile-time error becauseMapdoes not implementIterable(you must iterate overmap.keySet(),map.values(), ormap.entrySet()). - Underlying Desugaring:
- For an array
T[] arr, the compiler generates an indexed loop:for (int i = 0; i < arr.length; i++) { T var = arr[i]; ... }. - For an
Iterable<T> coll, the compiler generates an iterator loop:for (Iterator<T> it = coll.iterator(); it.hasNext(); ) { T var = it.next(); ... }.
- For an array
- No Array Mutation via Primitive Iteration Variable: In primitive arrays, assigning a new value to the iteration variable only modifies the local copy and does not alter the array element:
int[] numbers = {1, 2, 3}; for (int n : numbers) { n = n * 2; // Only modifies local copy 'n'! } System.out.println(numbers[0]); // Still prints 1! - ConcurrentModificationException: Modifying the size of a collection (such as
list.add(...)orlist.remove(...)) while iterating over it in an enhancedforloop causes the underlyingIteratorto detect a structural modification mismatch and throw aConcurrentModificationExceptionat runtime.
3. Branching Statements: break, continue, and Labels
Java provides jump statements to alter iterative execution:
break Statement
- Unlabeled
break: Terminates the innermost enclosingfor,while,do-while, orswitchconstruct and transfers control to the statement immediately following it. - Labeled
break LABEL: Terminates the statement or block identified byLABEL. The target can be any labeled statement or block{}, not only a loop!
BLOCK_A: {
System.out.println("Start Block A");
if (true) break BLOCK_A; // Legal: breaks out of labeled block
System.out.println("End Block A"); // Skipped
}
System.out.println("After Block A");
continue Statement
- Unlabeled
continue: Skips the remaining statements in the current iteration of the innermost enclosing loop and advances to the update step (infor) or condition check (inwhile/do-while). - Labeled
continue LABEL: Skips the remaining statements of the current iteration of the enclosing labeled loop and advances to the update/condition step of that outer loop. - Restriction:
continuecan ONLY be used inside a loop construct. Usingcontinueinside aswitch(outside a loop) or labeled non-loop block is a compile-time error.
OUTER: for (int i = 1; i <= 3; i++) {
INNER: for (int j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {
continue OUTER; // Jumps directly to i++ in OUTER loop!
}
System.out.print(i + "" + j + " ");
}
}
// Output: 11 12 13 21 31 32 33
4. Loop Architecture and Behavior Comparison
| Loop Type | Condition Evaluation Point | Minimum Iterations | Common Use Case |
|---|---|---|---|
while | Loop entry (pre-test) | 0 | When iteration count is unknown and condition may initially be false |
do-while | Loop exit (post-test) | 1 | When loop body must execute at least once (e.g., user input validation) |
Classic for | Loop entry (pre-test) | 0 | Counted loops with index variables and complex stepping |
Enhanced for-each | Implicit Iterator.hasNext() | 0 | Clean sequential traversal over Arrays and Iterable collections |
5. Compiler Reachability and Dead Code Rules
The Java compiler rigorously enforces reachability (JLS §14.21). Any statement that can never be executed causes a compile-time error:
- Statements After Unconditional Jumps: Statements immediately following an unconditional
break,continue,return, orthrowwithout a surrounding branch cause compilation errors:while (true) { break; // System.out.println("Unreachable"); // COMPILE ERROR: unreachable statement } - Infinite Loops and Trailing Code: An infinite loop created with constant condition
while(true)orfor(;;)makes code after the loop unreachable:while (true) {} // System.out.println("Done"); // COMPILE ERROR: unreachable statement while (false)vs.if (false)Exception:while (false) { ... }-> COMPILE ERROR (Unreachable statement).if (false) { ... }-> COMPILES SUCCESSFULLY (Special exemption in the JLS to support conditional compilation and debugging flags).do { ... } while (false);-> COMPILES SUCCESSFULLY (Body executes once, condition checked at exit).
Which of the following code blocks results in a compile-time error due to unreachable code?
What is the output of the following code snippet?
int[] nums = {1, 2, 3};
for (int n : nums) {
n = n * 2;
}
for (int n : nums) {
System.out.print(n + " ");
}
What is the output of executing the following nested loop construct?
int count = 0;
ROW: for (int r = 1; r <= 3; r++) {
COL: for (int c = 1; c <= 3; c++) {
if (r == 2 && c == 2) {
continue ROW;
}
if (r == 3 && c == 2) {
break ROW;
}
count++;
}
}
System.out.println("count=" + count);
Which of the following classic for loop declarations fails to compile?