这是我在这里的第一篇文章,所以请原谅任何协议错误。
我的问题只是试图理解以下 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 > 4
) false
,因此它会计算右操作数 (++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 > 4
是true
的,使整个条件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