在没有括号的Java中调用新对象的方法:操作违规的顺序?

Kyl*_*and 30 java parsing operator-precedence

根据此Java运算符优先级和关联性表,成员访问优先级高于new运算符.

但是,给定一个类myClass和一个非静态成员函数myFunction,以下代码行是有效的:

new myClass().myFunction();

如果.之前评估过new,该行怎么执行?换句话说,为什么不需要括号?

(new myClass()).myFunction();

我的猜测是,由于()共享优先.,因此myClass()首先进行评估,因此编译器甚至在评估new关键字之前就知道myClass正在调用具有零参数的构造函数.然而,这似乎仍然暗示第一行应该是相同的new (myClass().myFunction());,但事实并非如此.

Jac*_*ack 39

这是因为定义了Java语言的语法.运算符的优先级恰好在相同的词汇序列可以用两种不同的方式解析时发挥作用,但事实并非如此.

为什么?

因为分配定义如下:

Primary: 
  ...
  new Creator
Run Code Online (Sandbox Code Playgroud)

方法调用定义如下:

Selector:
  . Identifier [Arguments]
  ...
Run Code Online (Sandbox Code Playgroud)

这两个都用在这里:

Expression3: 
  ...
  Primary { Selector } { PostfixOp }
Run Code Online (Sandbox Code Playgroud)

所以会发生什么呢

new myClass().myFunction();
Run Code Online (Sandbox Code Playgroud)

被解析为

         Expression
             |
             |
    ---------+--------
    |                |
    |                |
  Primary        Selector
    |                |
    |                |
 ---+---            ...
 |     |
new   Creator 
Run Code Online (Sandbox Code Playgroud)

因此,根据优先级没有选择,因为Primary之前减少了.请注意,对于特殊情况喜欢

new OuterClass.InnerClass()
Run Code Online (Sandbox Code Playgroud)

类名实际上是在new运算符之前解析的,并且确实有处理该情况的规则.如果你想看到它们,请检查语法.