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.