【问题标题】:Evaluation order of Java operators && vs ||Java 运算符 && 与 || 的求值顺序
【发布时间】:2021-08-23 20:56:43
【问题描述】:

我有这个简单的代码块

int a = 10;
int b = 20;
int c = 30;
boolean result = a++ == 10 || b++ == 20 && c++ < 30;
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(result);

当我运行它时,控制台是

11
20
30
true

这个结果告诉我只有 a++ == 10 被评估。

正如我从https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html 中读到的, 运算符&amp;&amp; 的优先级高于||,应首先评估。在这本书 OCA Java SE 8 Programmer I Certification Guide 中,twist 2.4,一个类似的例子给出了所有逻辑操作数都将被评估的答案。 &amp;&amp; 首先评估,|| 是最后评估。

但结果给了我一个假设,即优先级仅用于对操作数和运算符进行分组。 从这个a++ == 10 || b++ == 20 &amp;&amp; c++ &lt; 30 到这个 a++ == 10 || (b++ == 20 &amp;&amp; c++ &lt; 30) 计算表达式时,它被|| 左侧的值true 短路。所以右边的表达式(&amp;&amp; 运算符)不会被计算。 因为如果先计算运算符&amp;&amp;,则bc的值会增加而不会增加。

我说的对吗?请帮忙。

【问题讨论】:

    标签: java logical-operators


    【解决方案1】:

    不带括号的计算顺序是从左到右。 由于第一次评估是正确的并且因为操作符是 ||其余的没有执行。 (如果你的第一个结果是假的,然后你有一个 && 操作符,也会发生同样的情况)。

    ++ 运算符总是在比较执行之后执行。 (在 C++ 中有两个不同的运算符 ++c 和 c++,然后您可以选择何时进行加法)

    好主意!!!

    【讨论】:

      【解决方案2】:

      tutorial page on operators 仅在执行 java 代码时为您提供运算符优先级的非正式描述。页面上显示的表格在 JLS 中不存在。执行/评估顺序取决于如何解析源代码以及如何生成解析树。

      a || b &amp;&amp; c(在此示例代码中)的代码片段将被解析为Expression

      Expression:
        LambdaExpression
        AssignmentExpression
      

      在这种情况下,它是AssignmentExpression

      AssignmentExpression:
        ConditionalExpression
        Assignment
      

      在这种情况下,它是ConditionalExpression

      ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression
        ConditionalOrExpression ? Expression : LambdaExpression
      

      在这种情况下,它是ConditionalOrExpression(第一行,而不是三元运算符):

      ConditionalOrExpression:
        ConditionalAndExpression
        ConditionalOrExpression || ConditionalAndExpression
      

      在这里,我们将把它翻译到第二行 (ConditionalOrExpression || ConditionalAndExpression),因为这里有 "||" 字符(实际的 || operator)。

      JLS 指定 || 运算符的左操作数首先由 15.7.1. Evaluate Left-Hand Operand First 求值:

      二元运算符的左侧操作数似乎在右侧操作数的任何部分被评估之前已被完全评估。

      它还指定|| 运算符是“短路的”,如15.24. Conditional-Or Operator || 中所定义:

      条件或运算符|| 运算符类似于|(第15.22.2 节),但仅当其左侧操作数的值为false 时才计算其右侧操作数。

      总的来说,这意味着计算左侧操作数(a++ == 10,这将增加变量 a),并且由于此比较结果为 true,因此不会计算右侧操作数。因此,b++c++ 都不会以任何方式进行评估。

      【讨论】:

      • 感谢您的努力。有了那个解析树,我想我现在明白了。
      【解决方案3】:

      这个结果告诉我只计算了 a++ == 10。

      这是语言定义规定的结果。

      但结果给了我一个假设,即优先级只是用于 分组操作数和运算符。

      你是对的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-15
        • 2010-11-29
        • 2011-11-03
        • 2021-07-12
        • 1970-01-01
        • 2014-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多