I know from somewhere that logical AND: &&
has a higher precedence than logical OR: ||
in Java, but until now I haven't found any clue about how this precedence really acts. What would happen if I didn't know about the precedence of the two and what mistake would I make?
I tried to write some code to PROVE the precedence of &&
and ||
but failed, for example:
boolExp1 || boolExp2 && boolExp3 || boolExp4
The code above produces the same results no matter the precedence of &&
and ||
, that is,
false || false && true || false
results in false
no matter what the precedence is.
I want a method or function that can PROVE the precedence of &&
and ||
. It should produce different results depending on the precedence of &&
and ||
. Is it possible?
If &&
didn't have higher precedence than ||
, then this expression:
a || b && c
would be evaluated like this:
(a || b) && c
To verify if this is the case or not,
you can generate all combinations of a
, b
, and c
,
and compare the result of these two expressions,
to see if they are always equal or not, that is:
a
, b
, and c
(a || b && c) == ((a || b) && c)
Sample code:
for (int i = 0; i < 8; ++i) {
boolean a = ((i >> 2) & 1) == 1;
boolean b = ((i >> 1) & 1) == 1;
boolean c = (i & 1) == 1;
boolean x1 = (a || b && c);
boolean x2 = ((a || b) && c);
if (x1 != x2) {
System.out.println(String.format("%s %s %s", a, b, c));
System.out.println(String.format(" %s || %s && %s => %s", a, b, c, x1));
System.out.println(String.format(" (%s || %s) && %s => %s", a, b, c, x2));
}
}
The output:
true false false true || false && false => true (true || false) && false => false true true false true || true && false => true (true || true) && false => false
As such, &&
has higher precedence than ||
.
You cannot prove anything useful about a programming language by just writing / running examples. For all you know, the compiler might be implemented so as to compile code in an illogical, inconsistent or non-deterministic fashion.
Even if you assume deterministic compilation and deterministic execution, the only thing that compiling / running an example proves is that that particular example exhibits a particular behavior. You cannot logically generalize from one example to another one, because without reference to a specification the compiler is just a black box. (Your very next example could be the one that is handled in a totally counter-intuitive fashion.)
The correct way to develop an understanding of a programming language is to read the language specification, a good textbook or a good tutorial. Combine this with writing code to confirm your understanding.
If you rely solely on reading example code and writing test programs, you are liable to pick up misconceptions, and bad habits that can be painful to unlearn.
Let's take your example expression:
boolExp1 || boolExp2 && boolExp3 || boolExp4
Now we believe that acts as:
boolExp1 || (boolExp2 && boolExp3) || boolExp4
right?
So let's suppose the opposite is true, and it's actually
(boolExp1 || boolExp2) && (boolExp3 || boolExp4)
What values of boolExp1
etc would give us different results?
Well, let's take:
boolExp1 = true
boolExp2 = false
boolExp3 = false
boolExp4 = false
Under the "&& has higher precedence" rules, the result would be true. Under the "|| has higher precedence rules", the result would be false. A quick test shows that the expression evaluates to true, however.
Of course, this doesn't actually prove that && has higher precedence than || - merely that || doesn't have higher precedence than &&. We could consider whether they have equal precedence - and test that with other expressions in a similar way... find a sample expression and values which would give different results under different precedence rules, and test them.
Ultimately though, I prefer:
I wouldn't use the first expression "as is" in the first place... because unless you actually know the precedence rules (and I suspect many Java devs don't - I couldn't swear that I'd have got && and || right) you're in the dark. Better to make it explicit and clear where there's any doubt.
I too had this same question but the answer was practically giving to me. Here is my example:
true || true && false
is equivalent to
true || (true && false)
So with this example it is easy to see that under the hood in Java the logical && has a higher precedence than ||.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With