Java中的优先级和执行顺序

2021-05-11  本文已影响0人  慕尼黑凌晨四点

参考:java - 关于 '&&'和 '||'优先级的令人困惑的示例

首先,程序中的优先级执行顺序是两个不同的概念。

代码示例

int a1 = 10;
int a2 = 20;
System.out.println(a1 < a2 || ++a1 > a2 && ++a2 < a1);
System.out.println(a1);
System.out.println(a2);

输出:

true
10
20

可见程序只对a1 < a2 进行了评估。

解释

我们知道Java中&&优先级高于||,所以

true || false && false

在Java中相当于:

 true || (false && false)

但是,这并不意味着程序会先执行括号中的内容

由于Java语言的执行顺序是从左到右,所以如果上述的布尔值是表达式的话,则会先计算左边表达式的内容,这叫执行顺序(或评估顺序)。

执行顺序是特定于语言的,Java与C++,JavaScript或许多其他语言不同,它具有严格的从左到右的评估。

15.7. Evaluation Order

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

15.7.1. Evaluate Left-Hand Operand First

The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.

引自 Java Language Specification

影响

执行顺序对程序是有影响的。

程序设计中有个名词叫短路求值[short-circuiting],是一种逻辑运算符的求值策略。意思是:只有当第一个运算数的值无法确定逻辑运算的结果时,才对第二个运算数进行求值。

例如,当AND的第一个运算数的值为false时,其结果必定为false;当OR的第一个运算数为true时,最后结果必定为true,在这种情况下,就不需要知道第二个运算数的具体值。

在一些语言中(如Lisp),默认的逻辑运算符就是短路运算符,而在另一些语言中(如JavaAda),短路和非短路的运算符都存在。

Java中&&和||就是短路求值的运算;而&和|就是非短路求值的运算了。

题目解释

最后回到一开始的这个题目:

a1 < a2 || (++a1 > a2 && ++a2 < a1)
           ^^^^^^^^^^^^^^^^^^^^^^^^
           Step 0, precedence and parenthesization
a1 < a2 || (++a1 > a2 && ++a2 < a1)
^^^^^^^
Step 1, left operand evaluated, variables resolved to values 10 and 20, condition is true

之所以程序只对a1 < a2 进行了评估,是因为程序发现a1 < a2等于true之后,后面的值可以不用算了

true || (++a1 > a2 && ++a2 < a1)
^^^^
Step 2, short circuits, left operand is not evaluated

所以后面的++a1++a2都不会被执行。

结论

主要结论是,优先级并不决定表达式的计算方式。它仅指示如何对表达式加上括号。另一方面,求值顺序可以准确地告诉我们表达式的求值方式,在Java中,总是从左到右。

上一篇 下一篇

猜你喜欢

热点阅读