考虑以下函数:
public static final int F(int a, int b) {
a = a - 1 + b;
// and some stuff
return a;
}
实现JVM的过程中是否必须在执行+ b
之前执行- 1
?
如果我们连接了系统分析器到JVM,我们会在+ 1
操作执行之前看到+ b
操作被执行吗?
考虑以下函数:
public static final int F(int a, int b) {
a = a - 1 + b;
// and some stuff
return a;
}
实现JVM的过程中是否必须在执行+ b
之前执行- 1
?
如果我们连接了系统分析器到JVM,我们会在+ 1
操作执行之前看到+ b
操作被执行吗?
其实,我不同意其他回答的观点。人们提到的JLS §15.7是讨论操作数的评估。也就是说,在表达式中
x = foo() - 1 + bar()
方法的调用顺序取决于其在代码中的位置。
相关部分为§15.7.3,其中规定:
除非可以证明替换后的表达式在值和可观察副作用方面等效,否则实现不得利用诸如结合律之类的代数恒等式将表达式重写为更方便的计算顺序。
由于表达式x = x - 1 + q
在所有方面等效于x = x + q - 1
,因此符合规范的实现允许重写该表达式(如果出于某种原因它认为这样更有效)。
foo()
可以影响 bar()
,因此 JVM 应该尊重顺序。对于 i > 0 && x/i > 3
,同样适用。代数上讲,a && b
等价于 b && a
,但是将 i > 0
放在前面可以避免第二个表达式中出现 NPE 错误。 - rdllopes是的,它使用Java语言规范第15.7节。
Java编程语言保证运算符的操作数按照特定的顺序从左到右进行评估。
建议代码不要过分依赖于此规范。当每个表达式仅包含一个副作用时,其最外层操作更清晰,并且代码不依赖于由于表达式从左到右的评估而产生的异常。
是的,尽管更重要的问题是这真的重要吗?在任何科学数学运算中,减法和加法具有相同的优先级并且可交换。也就是说:
x = input - 1 + q;
与
x = input + q - 1;
是一样的。
是的:
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.7
JVM将解释执行
x = input - 1 + q;
as
x = (input - 1) + q;
+
和-
具有相同的优先级,它们将按照它们出现的顺序执行。(
和)
),如下所示:
x = (a - b) + (c * (d - e))
是的,即使它不会影响加/减的结果,它也总是会这样。
在执行X + q - 1时,我觉得总会有副作用, 而当你应该执行X - 1 + q时。
当x + q的和超过Bignum 1时,从左到右的执行将成功...错序执行将产生溢出。
因此,无序执行具有副作用。
除非无序执行本身捕获了溢出,然后在需要时重新按正确顺序计算以避免副作用。
input
是什么? - Radu Murzeaint a = (buffer.get() & 255) | (buffer.get() & 255) << 8;
- Chameleon