在java中不带括号的新对象上调用方法:操作顺序冲突?

4jb9z9bj  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(394)

根据这个java操作符优先级和关联性表,成员访问的优先级高于 new 接线员。
但是,给定一个类 myClass 和一个非静态成员函数 myFunction ,以下代码行有效: new myClass().myFunction(); 如果 . 之前已评估 new ,如何执行该行?换句话说,为什么不需要括号? (new myClass()).myFunction(); 我猜是因为 () 与共享优先级 . ,的 myClass() 首先计算,因此编译器甚至在计算 new 关键字 myClass 正在调用参数为零的构造函数。然而,这似乎仍然意味着第一行应该与 new (myClass().myFunction()); ,事实并非如此。

hiz5n14c

hiz5n14c1#

我不同意从杰克的图表得出的结论。在编写语法时,它的非终结符和结构被设计成实现所描述语言的优先性和关联性。这就是为什么经典的bnf for表达式引入了“term”和“factor”非终结符——在算术的加法优先级之前强制执行正规乘法。
因此语法中的“primary->newcreator”和“expression->primary selector”意味着“newcreator”的优先级高于“primary selector”。
在我看来,语法是java操作符优先级和关联性表不正确的证据。

lnvxswe2

lnvxswe22#

这是因为java语言的语法是如何定义的。当同一个词法序列可以用两种不同的方式进行解析时,运算符的优先级就起作用了,但事实并非如此。
为什么?
因为分配定义如下:

Primary: 
  ...
  new Creator

方法调用定义在:

Selector:
  . Identifier [Arguments]
  ...

两者都用在这里:

Expression3: 
  ...
  Primary { Selector } { PostfixOp }

所以发生的是

new myClass().myFunction();

解析为

Expression
             |
             |
    ---------+--------
    |                |
    |                |
  Primary        Selector
    |                |
    |                |
 ---+---            ...
 |     |
new   Creator

所以根据优先级没有选择,因为 Primary 以前减少了。注意特殊情况,比如

new OuterClass.InnerClass()

类名实际上是在 new 而且确实有处理那个案子的规则。如果你想看的话,检查一下语法。

相关问题