Question

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).

Was it helpful?

Solution

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

OTHER TIPS

The grammar just describes a super set of valid Java source code. As far as I know, only the last TypeArgumentsOrDiamond may exist, but the (simplified) grammar you are looking at does not deal with this corner case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top