【发布时间】:2019-12-21 09:49:17
【问题描述】:
给定一个带有 3 个方法调用的表达式 f1() + f2()*f3(),java 评估(操作数)首先进行加法运算:
int result = f1() + f2()*f3();
f1 working
f2 working
f3 working
我(错误地)期望首先调用f2(),然后调用f3(),最后调用f1()。因为乘法应该在加法之前计算。
所以,我不明白 JLS 在这里 - 我错过了什么?
15.7.3。 评估方面括号和优先级
Java 编程语言尊重求值顺序 用括号显式表示,用运算符隐式表示 优先级。
在这个例子中,运算符优先级是如何被尊重的?
JLS 在15.7.5. Evaluation Order for Other Expressions 中提到了一些例外情况(方法调用表达式(§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
这里编译器有两个选择:
-
f1()+f2()- 先加法 -
f3()*f4()- 先乘法
但是“评估从左到右的规则”在这里很有魅力!
link 暗示在此类示例中,方法调用始终从左到右进行评估,而不管任何括号和关联规则。
【问题讨论】:
-
它按顺序评估函数。它根据 PEMDAS 应用数学运算符。
-
第一步,找出表达式中的值的方法 - 方法称为 LTR。然后找出表达式的值 - 评估尊重运算符的优先顺序。
-
您应该阅读 15.7.1 和 15.7.2。 15.7.3 只是意味着
f1()+f1()不会被2*f1()替换,3.0*x/4.0不会被(3.0/4.0)*x替换,等等......
标签: java operator-precedence evaluation jls expression-evaluation