简体   繁体   English

Java布尔表达式行为

[英]Java Boolean expression behavior

This is my first post here so please forgive any protocol errors. 这是我在这里发表的第一篇文章,请原谅任何协议错误。

My question is simply trying to understand what is happening with the following Java code. 我的问题只是试图通过以下Java代码来了解正在发生的事情。 I fully understand that the use of parentheses would clarify everything, but the resulting output seems to fly in the face of convention regarding Java order of operations. 我完全理解括号的使用会澄清一切,但结果输出似乎是在面对有关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);
   }
}

The output is: short 13 输出为:短13

It is obvious the ++num did not execute. 显然++ num没有执行。 If strict order of operations had been observed it should have been the first thing to happen. 如果观察到严格的操作顺序,它应该是第一件事。 It didn't. 它没有。 So next is the &&. 接下来就是&&。 If the && is done by order of precedence over the ||, then the same...the ++num should happen first. 如果&&按优先顺序超过||完成,则相同的...... ++ num应首先发生。 It didn't. 它没有。 So, to me it seems the output was determined with the || 所以,对我而言,似乎输出是用||确定的 executed first, shortciruiting the ++num and then, working with the &&, resulted in the short being printed. 首先执行, 接++ num,然后使用&&,导致打印。 Were the order of operation rules simply ignored and the Boolean expression executed left to right? 操作规则的顺序是否被忽略,布尔表达式是从左到右执行的? Is the increment operator causing the irregular behavior? 增量运算符是否导致不规则行为?

Thanks for any insight as to what is actually going on with this code. 感谢您对此代码实际发生的任何见解。

This has nothing to do with precedence/associativity (which deals with how expressions are parsed)... this has to do with Java evaluation order -- which is left to right . 这与优先级/关联性(它处理如何解析表达式)无关......这与Java评估顺序有关 - 这是从左到右 You appear to be misunderstanding how short-circuit logic works. 您似乎误解了短路逻辑的工作原理。

The && and || &&|| operators perform Conditional-AND and Conditional-OR operations on two boolean expressions. 运算符对两个布尔表达式执行条件AND条件OR运算。 These operators exhibit "short-circuiting" behavior, which means that the second operand is evaluated only if needed. 这些运算符表现出“短路”行为,这意味着仅在需要时才评估第二个操作数。


Now, let's attempt to evaluate this expression incrementally... 现在,让我们尝试逐步评估这个表达式......

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

Since total > 4 evaluates to true , the condition evaluates to true and the if branch is taken immediately rather than evaluating the rest of the conditional. 由于total > 4计算结果为true ,因此条件计算结果为true并且立即采用if分支而不是评估条件的其余部分。

If you change total to equal 4 , then the left-operand ( total > 4 ) of the short-circuit OR is false and thus it evaluates the right-operand ( ++num > 15 && total > 0 ). 如果将total更改为等于4 ,则短路OR的左操作数( total > 4 )为false ,因此它会计算右操作数( ++num > 15 && total > 0 )。

If you change num to equal 15 , then the short-circuit AND left-operand ( ++num > 15 ) evaluates to true and thus it finally evaluates the AND right-operand ( total > 0 ) to determine whether the conditional is true . 如果将num更改为等于15 ,则短路AND左操作数( ++num > 15 )的计算结果为true ,因此它最终计算AND右操作数( total > 0 )以确定条件是否为true If total > 0 is false, then the conditional is also false . 如果total > 0为false,则条件也为false

Below is the code rewritten for clarity to highlight the flow. 下面是为了清晰起见而重写的代码,以突出显示流程。

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

You can read more on Java conditional operators in the relevant Java Tutorial . 您可以在相关的Java Tutorial中阅读有关Java条件运算符的更多信息。

By using the double or (||), you activate java's short circuiting; 通过使用double或(||),可以激活java的短路; (use a single | if you don't want this). (使用单个|如果你不想要这个)。 As soon as it gets to a point where everything is true, and it hits a short circuit or (||), (or somethings false, and it hits a short circuit & (&&)), it will break out. 一旦它到达一切都是真的,并且它遇到短路或(||),(或某些事情是错误的,它会发生短路和(&&)),它就会爆发。 So In your case, total is bigger than 4, so it stops there (due to the ||), and returns true to the if statement, and prints out short; 所以在你的情况下,total大于4,所以它停在那里(由于||),并返回true到if语句,并打印出short; it never reaches the part that increments the num variable, as it sees no need to check that 它永远不会到达增加num变量的部分,因为它看不需要检查它

What's going on is short-circuit evaluation . 发生了什么是短路评估 total > 4 is true , making the entire conditional true . total > 4true ,使整个条件为true We don't even need to look at what follows after || 我们甚至不需要在||之后查看后面的内容 . This is a very common run-time optimization also present in C, C++, and Javascript (among many many others). 这是一种非常常见的运行时优化,也存在于C,C ++和Javascript(以及许多其他)中。 You observed its' side-effect. 你观察到它的副作用。

Note that short-circuiting can be used to your advantage (checking left-side of the || or && for a (non-) null value, for example) or it can confuzzle you (like it did in your question). 请注意,短路可以用于您的优势(例如,检查||&&左侧是否为(非) null值)或者它可能会使您混淆(就像您在问题中所做的那样)。 Use it wisely, young padawan. 明智地使用它,年轻的padawan。

the computer will under you boolean expression like this total>4 || 计算机将在你的布尔表达式下,如总计> 4 || (++num>15 && total>0) . (++ num> 15 && total> 0)。 It is like the expression in standard SQL. 它就像标准SQL中的表达式。 It finds the && and grabs 2 expressions on the left and right then put them in a bracket like i just did. 它找到&&并在左侧和右侧抓取2个表达式,然后像我刚才那样将它们放在一个括号中。 In your code, total=9>4 and ++num=14<15 and total=9>0 so the result is true ||(false && true) = true. 在你的代码中,total = 9> 4和++ num = 14 <15且total = 9> 0,因此结果为true ||(false && true)= true。 The terminal prints out "short" and num which is 13. 终端打印出“short”和num,即13。

Hope my answer will help you. 希望我的回答能帮到你。 If i am wrong, please correct me 如果我错了,请纠正我

i think it doesn't change the actual value of the variable when using in the if clause . 我认为在if子句中使用时它不会改变变量的实际值。 The value stored in the memory remains the same. 存储在存储器中的值保持不变。 it is like num+1>15 in the expression 它就像表达式中的num + 1> 15

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM