Конструктор со списком аргументов нескольких типов в грамматике Java

грамматика Java из спецификации языка Java v7 определяет следующие правила грамматики для конструкторов:

Primary:
    ...
    new Creator
    ...

Creator:  
    NonWildcardTypeArguments CreatedName ClassCreatorRest
    CreatedName ( ClassCreatorRest | ArrayCreatorRest )

CreatedName:   
    Identifier [TypeArgumentsOrDiamond] { . Identifier [TypeArgumentsOrDiamond] }

ClassCreatorRest: 
    Arguments [ClassBody]

Что меня озадачивает, так это правило CreatedName. По этому признаку такие выражения, как

new Class1<Integer>.Class2<Integer>();

были бы действительными конструкторами. Которыми они, конечно, не являются.

На самом деле, я не могу найти ни одного случая, когда цепочка идентификаторов (например, Class1.Class2) имела бы более одного списка параметров типа (например, <Integer>). Существуют ли такие случаи, или грамматика не имеет смысла?

Для справки эквивалентные грамматические правила приведены в раздел 15.9 JLS демонстрирует ту же проблему (эти правила ссылаются на нетерминал TypeDecl, который определен в раздел 4.3).


person Norswap    schedule 13.02.2013    source источник


Ответы (2)


Это правило выглядит как уловка, позволяющая использовать оба правила в одном правиле:

  • new Class1<...>();
  • new Class1.Class2<...>(); // Where Class2 is a static inner class

Допустимое выражение: new Class1<Integer>.Class2<Integer>(); никогда не будет компилироваться в Java, поскольку:

Тип члена Class1.Class2 нельзя квалифицировать с помощью параметризованного типа, так как он является статическим. Удалить аргументы из уточняющего типа Class1

person Christophe Roussy    schedule 13.02.2013
comment
Почему бы тогда не выразить правило в виде квалифицированного идентификатора (Class1.Class2), за которым следует необязательный список параметров типа? Это казалось бы очевидным. - person Norswap; 14.02.2013
comment
А как насчет этого: Identifier [TypeArgumentsOrDiamond] | Identifier.Identifier[TypeArgumentsOrDiamond] ? - person Christophe Roussy; 14.02.2013
comment
Я не очень понимаю ваш ответ: я спросил, почему Java делает это так, как есть, а не как Identifier (.Identifier)* TypeArgumentsOrDiamond?. - person Norswap; 27.02.2013

Грамматика просто описывает супернабор действительного исходного кода Java. Насколько я знаю, может существовать только последний TypeArgumentsOrDiamond, но (упрощенная) грамматика, на которую вы смотрите, не имеет дело с этим угловым случаем.

person C-Otto    schedule 13.02.2013