The java grammar from the Java Language Specification v7 specifies the following grammar rules for constructors:
Primary:
...
new Creator
...
Creator:
NonWildcardTypeArguments CreatedName ClassCreatorRest
CreatedName ( ClassCreatorRest | ArrayCreatorRest )
CreatedName:
Identifier [TypeArgumentsOrDiamond] { . Identifier [TypeArgumentsOrDiamond] }
ClassCreatorRest:
Arguments [ClassBody]
What puzzles me here is the CreatedName
rule. By that token, expressions such as
new Class1<Integer>.Class2<Integer>();
would be valid constructors. Which they of course aren't.
In fact, I can't find any case were a chain of identifier (e.g. Class1.Class2
) would have more than one type parameter list (e.g. <Integer>
). Do such cases exist, or does the grammar makes no sense?
For reference, the equivalent grammar rules given in the section 15.9 of the JLS exhibit the same problem (those rules reference the TypeDecl
non-terminal, which is defined in section 4.3).
This rule looks like a trick to allow both in a single rule:
new Class1<...>();
new Class1.Class2<...>(); // Where Class2 is a static inner class
The allowed expression: new Class1<Integer>.Class2<Integer>();
will never compile in Java since:
The member type Class1.Class2 cannot be qualified with a parameterized type, since it is static. Remove arguments from qualifying type Class1