Вызов метода для нового объекта в Java без круглых скобок: порядок нарушения операций?
Согласно эта таблица приоритетов и ассоциативности Java-операторов, доступ к члену имеет более высокий приоритет, чем оператор new
.
Однако, учитывая класс myClass
и нестационарную функцию-член myFunction
, следующая строка кода действительна:
new myClass().myFunction();
Если .
оценивается до new
, как эта строка может быть выполнена? Другими словами, почему не нужны скобки?
(new myClass()).myFunction();
Я предполагаю, что, поскольку ()
имеет приоритет с .
, сначала оценивается myClass()
, поэтому компилятор знает даже до того, как оценил ключевое слово new
, что конструктор myClass
с нулевыми параметрами называется. Однако это все еще кажется, что первая строка должна быть идентична new (myClass().myFunction());
, что не так.
Ответы
Ответ 1
Это связано с тем, как определяется грамматика языка Java. Приоритет операторов вступает в игру только тогда, когда одна и та же лексическая последовательность может анализироваться двумя разными способами, но это не так.
Почему?
Поскольку распределение определено в:
Primary:
...
new Creator
тогда как вызов метода определяется в:
Selector:
. Identifier [Arguments]
...
и оба используются здесь:
Expression3:
...
Primary { Selector } { PostfixOp }
так что происходит, что
new myClass().myFunction();
анализируется как
Expression
|
|
---------+--------
| |
| |
Primary Selector
| |
| |
---+--- ...
| |
new Creator
Таким образом, выбор невозможен по приоритету, потому что Primary
сокращен раньше. Имейте в виду, что для особой ситуации вроде
new OuterClass.InnerClass()
имя класса фактически анализируется перед оператором new
, и есть правила, чтобы справиться с этим делом. Проверьте грамматику, если вы хотите их увидеть.
Ответ 2
Я не согласен с выводами, сделанными на диаграмме Джека. Когда грамматика написана, ее нетерминалы и структура предназначены для реализации приоритета и ассоциативности описываемого языка. Вот почему классический BNF для выражений вводит "нетерминалы термина" и "фактор", чтобы обеспечить нормальное умножение до добавления приоритета арифметики.
Таким образом, тот факт, что "Первичный → Новый Создатель" и "Выражение → Первичный Селектор" в грамматике означает, что "новый Создатель" находится на более высоком уровне приоритета, чем "Первичный Селектор".
Мне кажется, что грамматика является доказательством неверности таблицы приоритетов и ассоциативности операторов Java.