Java 布尔表达式行为



这是我在这里的第一篇文章,所以请原谅任何协议错误。

我的问题只是试图理解以下 Java 代码发生了什么。 我完全理解使用括号会澄清一切,但结果输出似乎与有关 Java 操作顺序的惯例背道而驰。

public class Tester
{
   public static void main(String[] args)
   {
    int total=9, num=13;
    if (total>4 || ++num>15 && total>0)
    {
           System.out.println("short");
    }
    System.out.println(num);
   }
}

输出为:短13

很明显,++num 没有执行。 如果遵守严格的操作顺序,它应该是首先发生的事情。它没有。 所以接下来是&&。 如果 &&是按优先于 || 的顺序完成的,那么相同的...++num 应该首先发生。它没有。 所以,对我来说,输出似乎是用 ||首先执行,缩短 ++num,然后使用 &&,导致短线被打印出来。 是否简单地忽略了操作规则的顺序,并从左到右执行布尔表达式?增量运算符是否导致异常行为?

感谢您对此代码实际发生的事情的任何见解。

这与优先级/关联性(处理如何解析表达式)无关...这与Java求值顺序有关——从左到右。您似乎误解了短路逻辑的工作原理。

&&|| 运算符对两个布尔表达式执行条件 AND条件或操作。这些运算符表现出"短路"行为,这意味着仅在需要时评估第二个操作数。


现在,让我们尝试逐步计算此表达式...

total > 4 || ++num > 15 && total > 0

由于total > 4的计算结果为 true,条件的计算结果为 true,并且立即采用if分支,而不是评估条件的其余部分。

如果将total更改为等于 4 ,则短路 OR 的左操作数 (total > 4false,因此它会计算右操作数 (++num > 15 && total > 0)。

如果将num更改为等于 15 ,则短路 AND 左操作数 (++num > 15) 的计算结果为 true,因此它最终计算 AND 右操作数 (total > 0) 以确定条件是否true。如果total > 0为假,则条件也是false

下面是为清楚起见而重写的代码,以突出显示流。

if (total > 4) {
  System.out.println("short");
} else {
  if (++num > 15) {
    if (total > 0) {
      System.out.println("short");
    }
  }
}
System.out.println(num);

您可以在相关的 Java 教程中阅读有关 Java 条件运算符的更多信息。

通过使用双精度或 (||),您可以激活 Java 的短路;(如果您不想这样做,请使用单个 | )。一旦它到达一个一切都是真的点,它遇到短路或(||),(或错误的东西,它遇到短路和(&&)),它就会爆发。所以在你的例子中,total 大于 4,所以它停在那里(由于 ||),并返回 true 到 if 语句,并打印出 short;它永远不会到达递增 num 变量的部分,因为它认为没有必要检查

正在发生的事情是短路评估。 total > 4true的,使整个条件true。我们甚至不需要看||之后的内容.这是一种非常常见的运行时优化,也存在于 C、C++ 和 Javascript(以及许多其他)中。你观察到了它的副作用。

请注意,短路可以对您有利(例如,检查||&&左侧的(非)null值),或者它可以使您感到困惑(就像您的问题中所做的那样)。明智地使用它,年轻的帕达万。

计算机将在你布尔表达式下像这样总计>4 ||(++num>15 && total>0) .它就像标准SQL中的表达式。它找到 && 并在左侧和右侧抓取 2 个表达式,然后像我刚才一样将它们放在括号中。在您的代码中,total=9>4 和 ++num=14<15 和 total=9>0,因此结果为 true ||(假 &&&真) = 真。终端打印出"短"和数字,即 13。

希望我的回答对您有所帮助。如果我错了,请纠正我

我认为在

if 子句中使用时它不会改变变量的实际值。存储在内存中的值保持不变。它就像表达式中的 num+1>15

最新更新