Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Boolean expression behavior

Tags:

java

boolean

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. 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.

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

It is obvious the ++num did not execute. 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. 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. 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.

like image 270
user1580609 Avatar asked Aug 07 '12 01:08

user1580609


People also ask

What are the 3 Boolean expressions?

The three basic boolean operators are: AND, OR, and NOT.

How do you describe a Boolean expression?

A Boolean expression is a logical statement that is either TRUE or FALSE . Boolean expressions can compare data of any type as long as both parts of the expression have the same basic data type. You can test data to see if it is equal to, greater than, or less than other data.

Can you use == for boolean in Java?

When using ( == ) with booleans, If one of the operands is a Boolean wrapper, then it is first unboxed into a boolean primitive and the two are compared. If both are Boolean wrappers,created with 'new' keyword, then their references are compared just like in the case of other objects.


2 Answers

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. You appear to be misunderstanding how short-circuit logic works.

The && and || operators perform Conditional-AND and Conditional-OR operations on two boolean expressions. 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.

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).

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. If total > 0 is false, then the conditional is also 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.

like image 77
obataku Avatar answered Oct 03 '22 03:10

obataku


By using the double or (||), you activate java's short circuiting; (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; it never reaches the part that increments the num variable, as it sees no need to check that

like image 26
Alex Coleman Avatar answered Oct 03 '22 03:10

Alex Coleman