Search code examples
javalogical-operatorsshort-circuiting

Java logical operator (&&, ||) short-circuit mechanism


As I was reading a colleague's Java code, I stumbled upon an army of if/else statements. In these statements, several && and || operators were fighting each other without any help from parenthesis. I simplified the statements into:

if (true || true && false)
  return true;
else
  return false;

What do you think the result would be? Honestly, I thought it would be false, but it seems short-circuiting doesn't work like I expected. In this case, the result is true. The short-circuit mechanism seems to consider the whole expression as true when it finds true immediately followed by ||.

But in the reversed expression, what is the result?

if (false && true || true)
  return true;
else
  return false;

If we follow the same logic, it should be false. the first boolean is false and it is immediately followed by &&, but the result is true, once again. This makes sense to me, but it seems incompatible with our previous experiment.

So here's my theory:

If we find a true followed by ||, then it is true, no matter what might comes next, even if there is a long list of other logical operators coming after. But if we find a false followed by &&, it only short-circuits the next element, not the whole statement.

And here's my question:

Am I right? It seems a bit silly to me. Is true stronger than false?


Solution

  • It's simply because

    if (false && true || true)
    

    is equivalent to (&& has a higher precedence)

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

    which is

    if (false || true)
    

    which is... true.

    Note: In the expression true || true && false, the part true && false is called a dead code because it doesn't affect the final result of the evaluation, since true || anything is always true.


    It is worth mentioning that there exist & and | operators that can be applied to booleans, they are much like && and || except that they don't short circuit, meaning that if you have the following expression:

    if (someMethod() & anotherMethod())
    

    and someMethod returns false, anotherMethod will still be reached! But the if won't be executed because the final result will be evaluated to false.