We can see the difference by looking at JLS§14.14.2's description of how the enhanced for
works when handling an array:
The enhanced for statement is equivalent to a basic for statement of the form:
T[] #a = Expression;
L1: L2: ... Lm:
for (int #i = 0; #i < #a.length; #i++) {
{VariableModifier} TargetType Identifier = #a[#i];
Statement
}
Note how the variable is declared within the body of the loop, not the header of the loop. That is, your foo
function is like this:
void foo() {
{ // Freestanding block for scope, though not really needed as `foo` has
// nothing else in it
char[] a = foo; // T[] #a = Expression;
for (int i = 0; i < a.length; i++) {
char foo = a[i]; // {VariableModifier} TargetType Identifier = #a[#i];
}
}
}
That's why you get away with the shadowing in the enhanced for
, and not in the traditional for
, which needs to access the original array (to get its length
, to get the entry for i
, etc.).
More about the enhanced for
loop in How does the Java 'for each' loop work? and its answers.