JDK-6923696 : Allow mixed array brackets for enhanced for loop's variable
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 6u10
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2010-02-05
  • Updated: 2014-02-26
  • Resolved: 2011-07-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 rcFixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
javac 1.6.0_17, JLS 3

ADDITIONAL OS VERSION INFORMATION :
irrelevant.

EXTRA RELEVANT SYSTEM CONFIGURATION :
irrelevant.

A DESCRIPTION OF THE PROBLEM :
According to the JLS section on the syntax of the enhanced (iterable-based) for loop at http://java.sun.com/docs/books/jls/third_edition/html/statements.html#14.14.2:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement

Which clearly indicates that the following snippet:

for (int y[] : iterable)

should not be legal here (it is perfectly legit in a normal variable declaration). However, the syntax as stated in the JLS does not allow it.

Nevertheless, javac does allow it (and compiles as you would expect). Interestingly enough, even ecj (eclipse's compiler) allows it.

  Suggested fix: It's probably easier at this point to update the JLS compared to removing this 'feature' from javac.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile this:

public class Test {
    {
        int[][] x = null;
        for (int y[] : x) {}
    }
}


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
the above compiles fine; it should have generated a compiler error. Or, more likely, the JLS section 14.14.2 is wrong and javac is in fact correct.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Test {
    {
        int[][] x = null;
        for (int y[] : x) {}
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Print out the JLS, get out your red marker, and get creative. Or, perhaps somewhat more pragmatic:

move the [] to the type which is legitimate according to the JLS (and compiles fine in javac, of course):

for (int[] y : x) {}

Comments
EVALUATION This looks like an oversight by the JSR 201 EG. Given int[][] x = ... it should be legal to write either for (int[] y : x) ... or for (int y[] : x) ... And given int[][][] x = ... it should be legal to write for (int[][] y : x) ... or even (not recommended, as per 14.14.1!) for (int[] y[] : x) ... The grammar changes are described in 6442525, the master bug for the Java grammar. JLS3 14.14.2 does not discuss the type of the loop variable, but now it must. Borrowing from 14.4.1: "Let VT be the type of the loop variable as denoted by the Type that appears in the FormalParameter, followed by any bracket pairs that follow the Identifier in the FormalParameter." This text would lead into the translation described in 6690688.
16-04-2010