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?
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:
To trust the spec unless I have specific doubts
To use parentheses to make my intentions clear
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.
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:
For all combinations of a, b, and c
Verify that: (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 ||.
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 ||.
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.
I was looking at the java specification to see if they defined operator precedence for && and ||
Both are defined as left-associative and no operator precedence is defined.
See s. 15.7.3 a bit down from s. 17.7,
&& s. 15.23,
|| s. 15.24
i.e. Java defines:
boolExp1 || boolExp2 && boolExp3 || boolExp4
As:
((((boolExp1) || boolExp2) && boolExp3) || boolExp4)
A simple test is:
boolean a = true || false && false;
boolean b = false && false || true;
if (a == b) { // different precedence
if (a == true) {
System.out.println("&& has higher precedence than ||");
} else { // a == false
System.out.println("|| has higher precedence than &&");
}
} else { // a != b, same precedence
if (a == true) { // and b == false
System.out.println("&& and || have equal precedence, and are executed right to left.");
} else { // a == false, b == true
System.out.println("&& and || have equal precedence, and are executed left to right.");
}
}
Note that this accounts for the possibility that && and || could have equal precedence, and then, in that case, determines if they're executed left to right, or right to left.
Unfortunately, this does not account for precedence that changes or precedence based on inside to outside or outside to inside, or many other possible orders of operation, not to mention it can be defeated by malicious or broken compilers, malicious or broken computers, and cosmic rays.
Anyway, it's really hard to prove your compiler/computer/universe isn't messing with you. So check the language specification in addition to testing.
This is relyed upon all the time in lines like the following.
Clearly these examples would blow up if the first expression were not always evaluated and the second expression not evaluated conditionally.
// second expression on evaluated if text != null in both cases.
String text = ??
if (text != null && text.length() > 0)
if (text == null || text.length() == 0
public static void main(String[] args) {
boolean res = b(false,1) || b(true,2) && b(false,3) || b(false,4);
System.out.println(res);
}
static boolean b(boolean b, int i){
System.out.println(i);
return b;
}
// 1 2 3 4 false
Both && and || have the same precedence, Evaluation happens from left to right. Let me explain with an example.
public static void main(String[] args) {
System.out.println("Result = " + (arg1() || arg2() && arg3() || arg4()));
}
private static boolean arg1() {
System.out.println("arg1");
return false;
}
private static boolean arg2() {
System.out.println("arg2");
return true;
}
private static boolean arg3() {
System.out.println("arg3");
return true;
}
private static boolean arg4() {
System.out.println("arg4");
return false;
}
this evaluates to :-
arg1
arg2
arg3
Result = true
But now let me change arg3() to return false
private static boolean arg3() {
System.out.println("arg3");
return false;
}
this results in :-
arg1
arg2
arg3
arg4
Result = false
So to conclude.. the evaluation takes place form left to right i.e
arg1 || arg2 && arg3 || arg4
output && arg3 || arg4
output || arg4
output
Hope this helps.
Related
The following code results in false. Could anyone explain to me why? I am having some trouble understanding using truth tables. I am a beginner with java, thank you in advance for the help.
boolean x = false;
boolean y = true;
boolean z = true;
System.out.println((!x || y && !z));
I expected the printed line to be false but the correct answer is true.
The factors that come into play here are operator precedence, left-to-right evaluation, and the special "short circuit" nature of '&&' and '||'.
'and' binds tighter than 'or'.
Firstly, operator precedence means the expression is effectively
( (!x) || (y && !z) );
Given the short-circuit execution of '||', once we know that !x is true, the right-hand side does not get evaluated.
I wrote this hack to print out each term as it was evaluated:
static boolean P(String s, boolean x) { System.out.println(" "+s); return x; }
and then replaced every boolean term 'b' to a call to P("b", b):
{
... same as before...
System.out.println( P("!x",!x) || (P("y",y) && P("!z",!z)));
}
results in output
!x
true
note: nothing related to y or z printed.
I understand && and || are short circuited in Java (whereas & and | are not)
However, I do not understand why the following code (which starts off with short circuited OR but ends with && condition) is also short circuited:
String x, y;
if ( x.contains("this") || x.contains("that") && y.contains("something else")!= true)
I would think that even if condition x.contains("this") evaluates to true the program will still need to evaluate the last condition y.contains("something else") != true because there's the && operator before the last condition. But apparently this isn't the case.
Can anyone explain why?
Two factors are in play here to determine the order of evaluation:
Operation precedence, and
Short-circuiting rules
Since && has higher precedence than ||, operator && "stays closer to its operands", so your expression is parsed as follows:
Because both && and || operators are left-to-right associative*, Java evaluates this expression left-to-right, stopping as soon as it determines the outcome. In case the string contains "this" substring, evaluation stops without evaluating the &&.
Note: If you are not sure of the order of operations, you can always force the order that you want by parenthesizing parts of your predicate. If the expression is not entirely obvious to you, good chances are that it is going to be non-obvious to other readers, so adding some extra parentheses is a good idea.
* Some operators are right-to-left associative. For example, assignment operator a[i] = b + c evaluates b + c before evaluating a[i]. Thanks T.J. Crowder for a great comment.
This is because of operator precedence.
The equivalent form of your (a || b && c) is (a || (b && c))
Cf. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
...even if condition x.contains("this") evaluates to true the program will still need to evaluate the last condition y.contains("something else") != true...
Nope. :-) The operands to the || in that expression are
x.contains("this")
and
x.contains("that") && y.contains("something else")!= true
...because && has higher precedence than || (details). So if you have a || b && c, it's a || (b && c) (just like a + b * c is a + (b * c) rather than (a + b) * c). The precedence defines how the operands are grouped.
If you want the expression grouped differently, you can use () to group it.
if ( (x.contains("this") || x.contains("that")) && y.contains("something else")!= true)
It has to do with operator precedence. Most standard operators are binary, that is they take two inputs and produce an output. Whenever you have an expression with more than two operators, the compiler uses precedence and associativity rules to figure out how to transform that expression into one where it's clear what inputs each operations has.
In your case, you have an expression like A || B && C. && has higher precedence than ||, so the compiler will interpret it as A || (B && C), not like (A || B) && C, which you might get at by just looking at the expression.
This means that it's enough for A to be true for the whole expression to be true.
This is the way the syntax works in java as the && operations are grouped before the || opertaion, therefore when it reads the equation (A || B && C) it only see's comparing A || D (where D is really B && C). So when A is evaluated as True, it doesn't even need to evaluate B && C.
Refer to this link for further syntax related questions on the order of operations
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
&& is an operator with a higher precedence than ||.
Operators with higher precedence are evaluated before operators with lower precedence.
So here :
if ( x.contains("this") || x.contains("that") && y.contains("something else")!= true)
These two expressions are evaluated together :
x.contains("that") && y.contains("something else")!= true
So you get a conditional statement with a form such as :
if (something || somethingElse)
something is true, so somethingElse is never evaluated.
And the whole conditional statement is true.
Java have some operator precedence. You need to understand it to work with it.
First of all
In your if statement, you have two logical operators: || and &&.You know about short circuited. But you need to know that the &&operator will run first than ||.
AND operator (&&)
The && operator will, first, verify the left condition. There's no need to check two of them, to && return true, if the first one is true, then he can check the second.
OR operator (||)
The || operator will execute right after &&. It will verify if the two conditions return false, for this reason he needs to verify both.
Parentheses
You should know, but to make it work the way you want, you need to use parentheses (). To do it in the way you need, use () to present a new rule to your if statement:
if ( (x.contains("this") || x.contains("that")) && y.contains("something else")!= true)
I have a question about IF clause in Java.
I have and expression:
if ((someObject != null & connectedToTheInternet) || operate) {
// some action
}
Is my logic right: if someObject != null equals to true and connectedToTheInternet equals false then we have (someObject != null & connectedToTheInternet) equals false and then we have the following block:
if (false || operate) {
// some action
}
And if operate equals true then // some action will be triggered?
Just a first note: logical AND operator is "&&" and not just "&" (bitwise AND).
Following, your answer is YES... JVM will run conditions following your thinking.
By the way, I suggest you to read something abot short-circuit of these operators: it can be interesting if you are learning.
For example if you have if (a && (b || c) and a==false, then JVM won't evaluate b or c conditions because false && ... will be always false.
The same in the case of if (a || b || c && d): if a==true then JVM will ignore the other parts and consider it as true because true || .... will be always true.
Yes. if-clauses are evaluated from left to right. If no parenthesis are used, && has precedence, even higher precedence has ! (not) - similar to multiplication (AND), addition (OR) and negative numbers (-) in math (e.g. "A && (B || C) != A && B || C == (A && B) ||C") - I recommend to use parenthesis if you are unsure. This makes it possible to combine != null checks and calls to methods in the same if statement (e.g., if (object!=null && object.dosomething())).
Btw. there is a difference between & and && (short-circuit), when & is used, the second condition gets evaluated even if the first is false already. When && is used, Java doesn't check the second condition if the first one is false as the whole term cannot be true anymore - this is only important when the second condition is not a boolean variable but a method (which gets called or not -> side effects; this "skipping" is called short-circuit). Same for || and | where the second operator might not get evaluated if the first is already true (in case of ||).
Normally only ||and && are used.
Just for completeness: & is also the bitwise AND operator in Java.
if (false || operate) {
// some action
}
If operate true then if block executing.
In Oracle Java Docs it is mentioned that && operator has higher precedence over || operator.
Please look at the following code:
class TestLogicalOperators
{
public static void main(String... args)
{
if(doFalse() || doTrue1() && doTrue2() )
{
System.out.println(true+" inside if");
}
}
static boolean doTrue1()
{
System.out.println("doTrue1");
return true;
}
static boolean doTrue2()
{
System.out.println("doTrue2");
return true;
}
static boolean doFalse()
{
System.out.println("doFalse");
return false;
}
}
The output is:
doFalse
doTrue1
doTrue2
true inside if
Now if && operator has higher precedence over || operator shouldn't the methods doTrue1() and doTrue2() be evaluated first before doFalse()?
No.
The && operator has precedence, insofar as the expression:
doFalse() || doTrue1() && doTrue2()
... can also be read as:
doFalse() || ( doTrue1() && doTrue2() ) (note the parenthesis).
It doesn't mean the && expression will be evaluated before, your expression is still evaluated left to right.
The || operator can be a shortcut (i.e. no evaluation of second operand), if the first operand is true.
See example below:
// no shortcut, evaluates (true && false) and returns false anyway
System.out.println(false || true && false);
// no shortcut, evaluates (true && true) and returns true
System.out.println(false || true && true);
// shortcut (see warning), evaluates true and disregards "&&" expression
System.out.println(true || false && false);
You are missunderstanding the documentation. It doesn´t mean that the && operator will get executed first, it just says that the conditions surrunding a && are precedence over an other condition with a lower precedence.
In your example you can notice that the compiler is checking the condition of the if statement from left to right.
If we would go straigt from left to right the condition would be: (note parenthesis)
if((doFalse() || doTrue1()) && doTrue2() )
{
//This means either doFalse or doTrue1 would be true and doTrue2 would be true
}
But since the precedence of the && operator is higher then the on of the || operator it is read correctly as
if(doFalse() || (doTrue1() && doTrue2()))
{
//This correctly means either doFalse is true or doTrue1 and doTrue2 are true
}
NO, Normally first condition of OR operation is executed first. Which if evaluated to false, further checks second condition.
Otherwise it doesn't.
Operator && has preference over || but evaluation from left to right is still present and has precedende over operators as described in JLS §15.7
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
This question already has answers here:
What is the difference between & and && in Java?
(15 answers)
Closed 9 years ago.
I'm doing past paper for exam
public static void triangleTest( int a, int b, int c)
{
if ( a > 0 & b > 0 & c > 0 )
{
if ( a==b || b==c );
{
System.out.println("Equilateral");
}
else if ( a==b || a==c || b!=c )
System.out.println("Scalene");
}
else if ( a+b>c && a+c>b || b+c>a );
{
System.out.println(Isoceles);
}
}
else
{
System.out.println("");
}
}
I have been given this code and told to find mistakes, and when i checked the answers
if ( a > 0 & b > 0 & c > 0 )
this has been identified as mistake and && were meant to be used instead of & I ran the code and it worked fine with &, so my question would be what's what's the reasoning behind this?
& evaluates both values
where as && checks the first one if it's false it sets result as false.
If you are using & it will check second condition although first is false.
While in && it will not check next condition if first is false.
In some case it may cause exceptions.
For ex:
// Some Code
if ( a != null & a.length() > 0 ){
//coding part
}
above code will throw NullPointerException with & if a is null. because it will check second condition every time either first is true or false.
so it will go like this...
// Some Code
if ( a !=null && a.length() > 0 ){
//coding part
}
For more : refer this SO Que
& is a bitwise operator whereas && is a logical and operator.
Principles of short circuit does not apply in bitwise and operator i.e &.
& <-- verifies both operands
&& <-- stops evaluating if the first operand evaluates to false since the result will be false
Short circuiting leads to efficient code
&& is the logical and and it is short circuited. & is the bitwise and. Although for other cases it is very different; for booleans the (practical) difference is just that it doesn't short circuit.
Short circuiting means it skips evaluating conditions that can't affect the outcome. For exampple
if(cheapTest() && expensiveTest() && expensiveTest2())
If the first test is false the expresion must be false, so it can not bother with the expensive tests.
if(FALSE && DONTCARE && DONTCARE)
The reverse is true for | vs ||.
Protection against exceptions
This can be even more important where the second test may raise exceptions if evaluated, for example
if (someObject!=null && someObject.someTest())
In this case if someObject is null then someObject.someTest() never runs, this is a common pattern when null values are expected. Where you to use the bitwise and both tests would run in all cases and if someObject was null you would recieve a NullPointerException