Normally, we believe the following two pieces of code to be equivalent:
Iteration using for
for (i = 0; i < n; i++){ statement 1; statement 2; ... statement k; } |
Iteration using while
i = 0; while (i < n){ statement 1; statement 2; ... statement k; i++; } |
However, observe what happens if one of the internal statements is continue (or, more precisely in Java, continue l where l is a loop label).
l: for (i = 0; i < n; i++){ statement 1; statement 2; ... continue l; statement k; } |
l: i = 0; while (i < n){ statement 1; statement 2; ... continue l statement k; i++; } |
The statement continue l causes the loop l to start its next iteration without executing any of the statements that follow it in the loop. In the for loop, this still results in the increment i++ being executed since it is part of the loop definition and not a statement ``inside'' the loop. In the while loop, on the other hand, the increment i++ is skipped along with statement k so that the loop restarts with the same value of iq.
To fix this, we should use the try-finally construction (without a catch clause) as follows:
l: i = 0; while (i < n){ try{ statement 1; statement 2; ... continue l statement k; } finally{ i++; } }
Now, the continue l causes the try block to terminate prematurely, but the finally block is still executed before reentering the loop, so this version does preserve the semantics of the for.