java - JLS中f1() + f2()*f3()表达式的执行顺序和运算符优先级

标签 java operator-precedence evaluation jls expression-evaluation

给定一个具有 3 个方法调用的表达式 f1() + f2()*f3(),java 评估(操作数)首先进行加法运算:

int result = f1() + f2()*f3();

f1 working
f2 working
f3 working

我(错误地)期望 f2() 首先被调用,然后是 f3(),最后是 f1()。因为乘法应该在加法之前计算。

所以,我不明白JLS在这里 - 我错过了什么?

15.7.3. Evaluation Respects Parentheses and Precedence

The Java programming language respects the order of evaluation indicated explicitly by parentheses and implicitly by operator precedence.

在此示例中,运算符优先级究竟是如何得到遵守的?

JLS 在 15.7.5. Evaluation Order for Other Expressions 中提到了一些异常(exception)情况(方法调用表达式 (§15.12.4)、方法引用表达式 (§15.13.3)),但我不能将任何这些异常应用于我的示例。

我知道 JLS 保证二元运算的操作数是从左到右求值的。但是在我的示例中,为了理解方法调用顺序,有必要理解哪个操作(以及它的两个操作数!)首先被考虑。我在这里错了吗?为什么?

更多例子:

int result = f1() + f2()*f3() + f4() + f5()*f6() + (f7()+f8());

自豪地生产:

f1 working
f2 working
f3 working
f4 working
f5 working
f6 working
f7 working
f8 working

100% 从左到右,完全不考虑运算符的优先级。

int result = f1() + f2() + f3()*f4();

产生:

f1 working
f2 working
f3 working
f4 working

这里编译器有两个选项:

  1. f1()+f2() - 先加法
  2. f3()*f4() - 先乘法

但是“evaluate-left-to-right rule”在这里很有魅力!

link暗示在此类示例中,方法调用总是从左到右求值,而不管任何括号和关联性规则。

最佳答案

您缺少 15.7 下的文本:

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

表达式操作数的在表达式本身之前计算。在您的特定情况下,最外层的表达式是 f1() + [f2() * f3()]。我们必须首先评估 f1(),然后我们必须评估 f2() * f3()。其中,首先评估 f2(),然后是 f3(),然后是乘法(返回 + 的操作数的值).

关于java - JLS中f1() + f2()*f3()表达式的执行顺序和运算符优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57501441/

相关文章:

java - 命令行参数。

C:为什么 LLVM 从左到右评估 printf 而 GCC 从右到左评估?

c - 取消引用和后缀的优先级

c# - 成员引用和评估的分配顺序

scheme - 评估组合以递归处理 (+ 1 2)

java - 为什么很多 Java Stream 接口(interface)方法在参数中使用下界通配符而不是泛型类型?

java - 从 RxJava 1 到 RxJava 2

java - 从文本文件中获取值并将它们放入数组中

haskell - 如何在 GHCI 中发现函数的优先级和关联性?

C++ 运算符顺序评估