JAVA编程语言会遵循由括号显示表示和操作符优先级隐士表示的计算顺序。
Java编程语言的实现不应该利用代数特性,例如应用结合律来重写表达式,使其具有更方法的计算顺序,除非可以证明代替表达式与被代替的表达式在取值上和在可观察的副作用上是等价的,即使在面临多线程执行时也是如此,而且对于所有可能涉及其中的计算值都是如此。
在计算浮点的情况中,这条规则也会应用与无穷值和非数字NaN值。
例如:!(x<y)不能写作x>=y,因为如果x或者y是NaN,那么这些表达式具有不同的值。
特别的,看起来满足数据上的结合律的浮点计算,不可能满足计算结合律,这种计算必须不能被朴素的重排序。
例1:
public class MainTest1 {
public static void main(String[] args) {
double d=8E+307;
System.out.println(4.0*d*0.5);
System.out.println(2.0*d);
}
}
执行结果:
Infinity
1.6E308
因为第一个表达式上溢了,而第二个不会。
相比之下,整数加法和乘法在java编程语言中可证明是满足结合律的。
例如表达式a+b+c,其中a、b、c都是局部变量,产生的结果总是与(a+b)+c或a+(b+c)计算的结果相同。如果在代码中附近还有表达式b+c,那么java编译器可以使用这个公共子表达式。