9

I am unable to understand why following if blocks execute. How the if conditions will be evaluated?

public class Test
{
    public static void main(String[] args)
    {
        if (true || (false ||  true) && false)
        {
            System.out.println("How does this condition becomes true.");
        }

        if (false && (false ||  true) || true)
        {
            System.out.println("Same with this condition, why is it true.");
        }
    }
}
Rahul khandelwal
  • 331
  • 3
  • 14
  • refer this link https://stackoverflow.com/questions/2137690/java-operator-precedence-guidelines – Tejal Jul 20 '18 at 10:58

4 Answers4

15

&& has higher precedence than || (source). So adding in parens to emphasize how those are being evaluated:

    if (true || ((false ||  true) && false))
// -------------^-------------------------^

and

    if ((false && (false ||  true)) || true)
// -----^-------------------------^

As you can see, you end up with x || y where x is true in the first example, and y is true in the second example. Naturally both true || false and false || true are true.

You can see it in action by using a method that outputs what it's doing (live copy) (remember that both || and && short-circuit, meaning they don't evaluate operands that cannot change the result):

public class Test
{
    private static boolean b(String label, boolean value) {
        System.out.println(label + ": " + value);
        return value;
    }
    public static void main(String[] args)
    {
        if (b("1", true) || (b("2", false) || b("3", true)) && b("4", false))
        {
            System.out.println("How does this condition becomes true.");
        }

        if (b("5", false) && (b("6", false) || b("7", true)) || b("8", true))
        {
            System.out.println("Same with this condition, why is it true.");
        }
    }
}

When run, that outputs:

1: true
How does this condition becomes true.
5: false
8: true
Same with this condition, why is it true.
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 5
    Worth noting: even if you *know* the rules of precedence (and a big number of Java devs don't), it's almost always easier to quickly figure out the logic if you include the parentheses. It also conveys to a reader what your exact intention was -- the number of times I've had to try to infer whether a colleague actually understood the precedence rules when they wrote an expression is not even funny. – Michael Jul 20 '18 at 11:05
  • 1
    @Michael You are correct about the use of parentheses in conditions, I was looking into some legacy code when I found this. As I did't know operator precedence rule so I couldn't figure out how it was working. – Rahul khandelwal Jul 31 '18 at 17:31
5

First of all, you must already know false || true is true.

Apart from that, you need to know the other two things:

The && and || operators "short-circuit", meaning they don't evaluate the right hand side if it isn't necessary.

When operators of equal precedence appear in the same expression, a rule must govern which is evaluated first. All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.

From the precedence table, we know && is higher than ||.

So in your question, let's do the basic reasoning.

if (true || (false || true) && false)

true || no_matter_what_is_in_right_side will be true, so we got a true.

if (false && (false || true) || true)

This one is trickier than the previous, this time we have to consider the annoying precedence. We do the reasoning as:

false && no_matter_what_is_in_right_side will be false and all we have left is:

false || true

Again we have true in the end.

But if you already noticed the trick: we start from the rightmost true then we can do the reasoning as the previous one directly get the true.

As Michael mentioned, we'd better use parenthesis to express the exact order instead of relying on the precedence, which is actually hard to remember ##.

Hearen
  • 7,420
  • 4
  • 53
  • 63
0

Well we will take a look at the first line:

if (true || (false ||  true) && false)

Based on priority, everything between () will be evaluated first. So, that will be false || true, we can write || as OR, that means we get true OR false, in that case it will be true, since one of the two values is true.

Okay let's move on, it becomes like this:

if (true || true && false)

Now we come to your confused part. We don't read from left to right in this case. We need to take a look at && first instead of ||. So we need to check the true && false evaluation, which will become false:

Then we are left with the following statement:

if (true || false)

Which will become true of course. The same happens for the second one.

See mor here: http://bmanolov.free.fr/javaoperators.php

gi097
  • 7,313
  • 3
  • 27
  • 49
  • Sorry to say this: we do not do `math` here since there is **short circuiting** in logical operation – Hearen Jul 20 '18 at 11:10
0

Using || the condition is true if at least one operand is true. E.g. false || true results in true.

So your first condition is true because of the first true (true || ....

if (true || (false ||  true) && false)
......|...............................

The second condition is true because of the last true ... || true)

if (false && (false ||  true) || true)
...................................|..

Take a look at the Truth Table.

OR
  P       Q     P||Q
--------------------
  T       F      T
  F       T      T
  T       T      T
  F       F      F
Rene Knop
  • 1,788
  • 3
  • 15
  • 27