5.2 Standard for Loops & Control Flow
Key Takeaways
- The standard for loop executes in a strict chronological four-phase sequence: initialization executes once, followed by a pre-iteration condition check, body execution, and the update expression.
- Multiple variables declared in the initialization header must share the exact same data type and be separated by commas.
- The update header expression permits multiple comma-separated statements evaluated left-to-right, but the condition expression must evaluate to a single boolean value.
- All three expressions in for (init; condition; update) are optional, but the two separating semicolons are mandatory; an omitted condition expression defaults to true.
- Variables declared within the for loop initialization header have block scope strictly confined to the loop header and body, ceasing to exist upon loop termination.
5.2 Standard for Loops & Control Flow
[!NOTE] Exam Focus: In the 1Z0-811 examination, the standard
forloop is tested extensively through intricate code tracing questions. Oracle examiners evaluate candidate understanding of the precise four-phase execution order, variable scope boundaries, rules governing multiple variables in the header, optional expressions, and deceptive syntax traps like empty loop bodies created by trailing semicolons.
While condition-driven loops (while and do-while) are ideal when repetition depends on external conditions or unpredictable runtime state, the standard for loop is the primary idiomatic construct used when the exact number of iterations is known before entering the loop. By consolidating counter initialization, boundary testing, and step modification into a single, compact header, the for loop provides clean, structured iteration.
Anatomy of the Standard for Loop Header
The standard for loop header consists of three functional expressions enclosed in parentheses and separated by exactly two semicolons:
for (initialization; terminationCondition; updateExpression) {
// Loop body: statements executed repeatedly
}
Each constituent part plays a distinct operational role:
- Initialization (
initialization): Executed exactly once when the loop is first encountered. It is primarily used to declare and initialize one or more loop control variables. - Termination Condition (
terminationCondition): A boolean expression evaluated before each iteration. If this expression evaluates totrue, the loop body executes. If it evaluates tofalse, the loop terminates immediately, and control jumps to the statement following the loop's closing brace. - Update Expression (
updateExpression): Executed after each execution of the loop body, immediately prior to the next condition evaluation. It is typically used to increment, decrement, or otherwise modify the loop control variable. - Loop Body (
{ ... }): The block of statements executed repeatedly as long as the condition remainstrue.
The Exact Four-Phase Chronological Order of Execution
A frequent stumbling block on the 1Z0-811 examination is confusion regarding the exact order in which for loop components execute. Under the Java Language Specification (JLS §14.14.1), execution adheres to an invariant four-phase cycle:
┌───────────────────────────────┐
│ Phase 1: Initialization │
│ (Executes ONCE upon entry) │
└──────────────┬────────────────┘
│
▼
┌───────────────────────────────┐
┌──────>│ Phase 2: Condition Test │<─────────────────┐
│ │ (Evaluated before every pass) │ │
│ └──────────────┬────────────────┘ │
│ │ │
│ [true] │ [false] │
│ ┌────────┴────────┐ │
│ ▼ ▼ │
│ ┌─────────────────┐ ┌──────────────────────┐ │
│ │ Phase 3: Body │ │ Exit Loop │ │
│ │ Statements │ │ (Subsequent code) │ │
│ └────────┬────────┘ └──────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ Phase 4: Update Expr │ │
│ │ (Runs after body) │ │
│ └────────┬────────────────┘ │
│ │ │
└─────────────┴────────────────────────────────────────────┘
| Phase | Component | Frequency | Execution Timing |
|---|---|---|---|
| Phase 1: Init | initialization | Exactly once | First statement executed upon entering the loop construct |
| Phase 2: Test | terminationCondition | Before every pass | Immediately after Phase 1 on first pass; after Phase 4 on subsequent passes |
| Phase 3: Body | Loop body statements | Per iteration | Executes only if Phase 2 evaluates to true |
| Phase 4: Update | updateExpression | Per iteration | Executes immediately following the completion of the loop body |
Step-by-Step Execution Trace
Consider tracing this standard counter loop:
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
System.out.println("Done");
- Phase 1 (Init):
int i = 1allocatesiwith initial value1. - Phase 2 (Test):
1 <= 3istrue. Proceed to body. - Phase 3 (Body): Outputs
i = 1. - Phase 4 (Update):
i++incrementsifrom1to2. - Phase 2 (Test):
2 <= 3istrue. Proceed to body. - Phase 3 (Body): Outputs
i = 2. - Phase 4 (Update):
i++incrementsifrom2to3. - Phase 2 (Test):
3 <= 3istrue. Proceed to body. - Phase 3 (Body): Outputs
i = 3. - Phase 4 (Update):
i++incrementsifrom3to4. - Phase 2 (Test):
4 <= 3isfalse. The loop terminates immediately. - Exit: Execution resumes at the print statement, outputting
Done.
[!IMPORTANT] Critical Exam Rule: Observe that upon loop termination, the loop counter
iwas incremented to4. The update expression runs before the condition is tested, not after. It is the condition test that fails that halts execution.
Declaring Multiple Variables: The Same-Type Rule
Java allows multiple variables to be declared and initialized within the initialization clause of a for loop header, using commas as delimiters. However, strict type rules apply:
The Same-Type Mandate
In the initialization clause, you may declare multiple variables, but all declared variables must share the exact same data type:
// LEGAL: Both i and j are declared as int
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println(i + " and " + j);
}
Attempting to declare variables of different types in the loop header produces a compile-time error:
// COMPILE ERROR: <identifier> expected, syntax error
for (int i = 0, double d = 1.5; i < 5; i++) { // WILL NOT COMPILE!
// ...
}
If loop management requires variables of multiple types, they must be declared before the loop header, and initialized or referenced without redeclaring their types in the header:
int count = 0;
double rate = 1.05;
for (; count < 5; count++, rate += 0.1) { // LEGAL: Declared outside beforehand
System.out.println("count=" + count + ", rate=" + rate);
}
Comma-Separated Expressions in Update Clauses
The update section of the loop header can contain multiple statements separated by commas. These expressions are evaluated sequentially from left to right after each iteration:
for (int a = 1, b = 100; a <= 3; a++, b -= 25) {
System.out.println("a=" + a + ", b=" + b);
}
// Output:
// a=1, b=100
// a=2, b=75
// a=3, b=50
[!CAUTION] Prohibition of Commas in Condition: Unlike the initialization and update clauses, the termination condition clause cannot use commas. The condition must evaluate to a single
booleanvalue. Combining multiple conditions requires logical boolean operators (&&,||), such asfor (int i = 0, j = 10; i < 5 && j > 0; i++, j--).
Scope and Lifetime of Loop Variables
Variable scope—the region of the program where a variable can be referred to by its simple identifier—is a prominent theme on the 1Z0-811 examination.
1. Loop Header Scope
When a variable is declared in the for loop header, its scope is strictly restricted to the loop header and the loop body. As soon as the loop terminates, the variable ceases to exist:
for (int index = 0; index < 3; index++) {
System.out.println(index); // LEGAL: index is in scope
}
// COMPILE ERROR: cannot find symbol variable index
System.out.println("Final index: " + index);
2. Redeclaration and Shadowing Conflicts
If a variable is already declared in the enclosing method or block scope, attempting to declare another variable with the same name in the for loop header triggers a compile-time error:
int x = 50;
// COMPILE ERROR: variable x is already defined in method
for (int x = 0; x < 5; x++) {
System.out.println(x);
}
To use an existing variable as a loop counter, simply reuse it without prepending a type declaration:
int x = 50;
for (x = 0; x < 5; x++) { // LEGAL: Reassigns the existing variable x
System.out.println(x);
}
System.out.println("Final x: " + x); // LEGAL: Outputs 5
Optional Nature of Header Expressions and the Infinite Loop
All three expressions in a standard for loop header are completely optional. However, the two separating semicolons are strictly mandatory:
// The canonical infinite loop in Java
for ( ; ; ) {
System.out.println("Infinite Loop");
}
Rules for Omitting Components
- Omitting Initialization: When the loop control variable is declared and initialized prior to loop entry:
int idx = 0; for (; idx < 5; idx++) { ... } - Omitting Condition: When the termination condition is omitted, the Java compiler defaults the condition to the literal
true. Therefore,for (;;)creates an infinite loop that continues until an internalbreak,return, or thrown exception terminates it. - Omitting Update: When the loop counter is updated inside the body of the loop:
for (int i = 0; i < 5; ) { System.out.println(i); i++; // Incremented inside the body } - Syntax Violation: Writing
for ()orfor (;)results in a compile-time syntax error (';' expected). Exactly two semicolons must always be present.
High-Frequency Exam Traps and Pitfalls
1. Off-by-One Boundary Traps (< vs. <=) with Arrays
Arrays in Java are zero-indexed, meaning valid indices range from 0 to array.length - 1. Using <= instead of < with array.length is a classic bug that compiles cleanly but crashes at runtime:
int[] numbers = {10, 20, 30}; // length is 3; valid indices: 0, 1, 2
for (int i = 0; i <= numbers.length; i++) { // TRAP: When i is 3, crashes!
System.out.println(numbers[i]);
}
// Output: 10, 20, 30, followed by java.lang.ArrayIndexOutOfBoundsException: 3
2. Dual-Increment Traps
When a counter variable is incremented inside both the loop body and the header update expression, the counter advances twice per iteration:
int count = 0;
for (int i = 1; i <= 6; i++) {
count++;
i++; // Incrementing inside body as well!
}
System.out.println("count = " + count);
Tracing this loop:
- Pass 1:
i=1(1 <= 6is true).countbecomes1. Body incrementsito2. Header updatesito3. - Pass 2:
i=3(3 <= 6is true).countbecomes2. Body incrementsito4. Header updatesito5. - Pass 3:
i=5(5 <= 6is true).countbecomes3. Body incrementsito6. Header updatesito7. - Pass 4:
i=7(7 <= 6is false). Loop terminates. The final output iscount = 3.
3. The Accidental Semicolon Trap
Placing an unintended semicolon immediately following the for loop header creates an empty statement as the loop body:
int sum = 0;
for (int k = 0; k < 5; k++); // Empty body! Loop runs 5 times doing nothing.
{
sum += 1; // Executes once after loop finishes
}
System.out.println(sum); // Prints 1, NOT 5!
If the block had attempted to access k (sum += k;), a compile-time error would have occurred because k went out of scope when the empty loop body terminated!
What is the output of the following Java code snippet?
int total = 0;
for (int i = 0, j = 10; i < 4 && j > 4; i++, j -= 2) {
total += (i + j);
}
System.out.println(total);
Which of the following standard for loop declarations will trigger a compile-time error in Java SE 8?
What is the result of attempting to compile and execute the following Java code?
int count = 0;
for (int i = 0; i < 5; i++);
{
count++;
}
System.out.println("count=" + count);