15

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?

9
  • 19
    docs.oracle.com/javase/tutorial/java/nutsandbolts/… && has higher precedence than || as mentioned in existing answers (just wanted to provide the link) Commented May 4, 2015 at 14:48
  • 1
    Anyway you should ask your colleague to write parenthesis in this case, to avoid errors that are likely to happen when someone will add a new condition in this code! Commented May 4, 2015 at 14:51
  • 11
    Short-circuting will never change the result of a boolean expression. The only thing short-circuting does is avoid executing the remainder of the expression. Commented May 4, 2015 at 16:41
  • 2
    @Jägermeister, in fairness to the OP, if they'd asked whether the code should be written like that, the question would probably have been closed as being primarily opinion based Commented May 4, 2015 at 17:03
  • 8
    it's not about short-circuit, it's about operator precedence Commented May 4, 2015 at 19:32

6 Answers 6

58

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.

Sign up to request clarification or add additional context in comments.

15 Comments

Alright, so it works like "1 + 1 * 2 = 3". I didn't know such a thing (the precedence), existed for the && and || operators. Thank you very much :)
@JasonBerger false && true || true is very similar to 0 * 1 + 1, see Boolean Algebra for details
if (someMethod() & anotherMethod()) - Don't encourage writing code like this. That should be split into multiple lines.
If you actually want both methods to be executed (perhaps because they have side effects), they shouldn't be in an if. That's just incredibly confusing.
I'm willing to admit the possibility that it can be useful (though I'd have to see it to believe it), but "it's there to be used" is a very weak argument unless you think Java is a perfect language. Personally I consider the existence of these operators to be a flaw in Java.
|
15

The && has higher operation precedence over the ||, thus it wins.

Comments

9

According to Java tutorials && has higher precedence over ||

So your true || true && false would be evaluated as true || (true && false)

And your false && true || true would be evaluated as (false && true) || true

Resulting in an output of true in both case.

Comments

5

for &&:

false && ... => false

for ||:

true || ... => true.

And precedence for && is higher than ||.

See more: Operator Precedence in Java

Comments

3

Because of the precedence of && on ||, (true || true && false) this will be evaluated as (true || (true && false)) -> (true || (false)) -> true

See the precedences rules: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

Comments

1

I see what you were trying to do, but before operating on parentheses it's good to have the language's specification handy. I've known a few programmers who have gone so far as to keep the important bits, like operator precedence, on their walls.

The second part is to know whether your alterations are going to make any sense to the other people in your workplace; if removing parentheses compromises the meaning of an operation to someone else working on the code, then it could ultimately be detrimental.

The optimizer will generally take care of it for you, so when in doubt, leave them in there.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.