I was testing the precedence between && and || and I had an example that was confusing. In Java, && has higher operator precedence than the operator ||.
So if we have those 3 expressions:
//expr1 = true , expr2 = false; expr3 = false;
if(expr1 || expr2 && expr3);
It should be evaluated as:
if(expr1 || (expr2 && expr3));
So expr2 && expr3 should be evaluated before expr1. However, this example:
int a1 = 10;
int a2 = 20;
System.out.println(a1 < a2 || ++a1 > a2 && ++a2 < a1);
System.out.println(a1);
System.out.println(a2);
Outputs:
true
10
20
That proves that only a1 < a2 is evaluated.
Can you explain why this is the case?
The expression is short-circuiting. From the link:
when the first argument of the AND function evaluates to false, the overall value must be false; and when the first argument of the OR function evaluates to true, the overall value must be true.
It sees that the rest of the condition doesn't matter because one of the operands of || is already true (10 < 20). If one of the operands is true, then no matter what the rest of the condition is, it's true.
You may use bitwise & and | to prevent this.
But, the ( expr2 && expr3 ) should be evaluated before expr1, no ?
No. You have to separate concepts of precedence and evaluation order.
Precedence: Dictates the parenthesization of an expression, not the order in which an expression is evaluated. For an example:
true || false && false
Is parenthesized to this because && has higher precedence than ||:
true || (false && false)
This does not mean that things in parentheses is evaluated first in Java's case. Precedence just clarifies what the operands of an operator are, in this case false and false, where as in this case:
(true || false) && (false || false)
The operands for && are true and false, not false and false.
Evaluation Order: Describes in what order each operand is evaluated and operator is applied and is sometimes language specific. This dictates how an expression is evaluated, unlike precedence.
In this case, your example:
true || false && false
As established earlier, becomes this due to precedence:
true || (false && false)
But Java, unlike C++, JavaScript, or a number of other languages has a strictly left to right evaluation. Per the Java Language Specification:
15.7. Evaluation Order
The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.
15.7.1. Evaluate Left-Hand Operand First
The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated.
So, when you have:
true || (false && false)
Java first evaluates the left operand which turns out to be true. Then the whole condition short circuits. The right operand of || in the parentheses is never evaluated at all. The same goes for your other example:
a1 < a2 || (++a1 > a2 && ++a2 < a1)
^^^^^^^^^^^^^^^^^^^^^^^^
Step 0, precedence and parenthesization
a1 < a2 || (++a1 > a2 && ++a2 < a1)
^^^^^^^
Step 1, left operand evaluated, variables resolved to values 10 and 20, condition is true
true || (++a1 > a2 && ++a2 < a1)
^^^^
Step 2, short circuits, left operand is not evaluated
Take another more complex example:
false || false || true && (false || true) || false
Due to precedence, it becomes:
false || false || (true && (false || true)) || false
Then, evaluation begins, left to right:
false || false || (true && (false || true)) || false
^^^^^^^^^^^^^^
Step 1, false || false, does not short circuit, right operand is evaluated, is false
false || (true && (false || true)) || false
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Step 2, false || (true && (false || true)), does not short circuit, right operand is evaluated
Step 2A, (true && (false || true)), does not short circuit, right operand is evaluated
Step 2B, (false || true), does not short circuit, right operand is evaluated, is true
Step 2C, (true && true), does not short circuit, right operand is evaluated, is true
Step 2D, false || true, does not short circuit, right operand is evaluated, is true
true || false
^^^^
Step 3, true || false short circuits, right operand is not evaluated, is true
Thus the whole expression evaluates to true. The whole expression was evaluated left to right the whole way through. Precedence only dictated the operands of an operator via parenthesization, not the evaluation order.
Further reading at Eric Lippert's explanatory article on precedence vs associativity vs evaluation order as mentioned by Daniel Pryden, it clears up a lot of the confusion.
The main takeaway is that precedence does not dictate in what an expression is evaluated. It only dictates how an expression should be parenthesized. Evaluation order, on the other hand, tells us exactly how an expression is evaluated, and in Java's case is always left to right.
The first line prints true because of short-circuiting the || operator.
a1 < a2 is true and so the rest of the boolean expression doesn't need to be evaluated and true is returned.
expr2 should be evaluated before expr1
is incorrect, as operator precedence affects the structure of the expression, rather then the evaluation order (in most cases). If you were to re-order the expression so that it was (expr2 && expr3) || expr1, then yes, expr2 would be evaluated before expr1
Precedence:
boolean result = a || b && c
In order to have the correct value according to the rules of precedence, the compiler must logically evaluate this as:
boolean x = b && c
boolean result = a || x
This speaks to your point that b && c must be evaluated before result can be calculated. However, in Boolean algebra, it is possible to write expressions whose results do not depend on all the operands. This fact is exploited to enable a compiler optimization called short circuiting.
Short Circuiting:
For any Boolean expression:
a || b
the result does not depend on b if a evaluates to true. When a is true, it does not matter if b evaluates to true or false. Because of this, the compiler executes:
a || b && c
as if it had been written:
boolean result = a;
if (!a) result = b && c;
Note that executed this way, the rules of precedence are still respected. The expression is not evaluated as (a || b) && c. Since the overall result of the expression does not depend on (b && c) in the case where a is true, b && c is simply never evaluated.
This is a good thing. Short circuiting allows you to write correct programs when the correctness of one operand depends on the correctness of another. For example:
if (myString == null || !myString.isEmpty() && myString != "break") return;
Without short circuit evaluation, the boolean expression could throw a NullPointerException. However, because of short circuit evaluation, this expression, as written, can never throw a NullPointerException.
Short circuiting can also be used as a performance optimization. If evaluating one operand is extremely expensive, evaluating another first can save the execution time needed to evaluate an operand whose value does not influence the final result of the whole expression.
Even when you use explicit parentheses as in
if (expr1 || (expr2 && expr3))
expr1 is evaluated first, since the operands of operators are evaluated from left to right. Since || is a short circuited operator, the second operand ((expr2 && expr3) in your case) will only be evaluated if expr1 is false.
When you remove the parentheses, the operator precedence only comes into play if expr1 is false. In that case the && operand will be evaluated before the || operator and its value will be the second operand of the || operator.
This is because of short-circuiting. Where the first expression is evaluated first and if it's able to derive the result as true then it concludes there & would not even go for rest of the expression.If the first expression results as false then the other condition will be checked and the outcome will be derived.
To know more on operator precedence. Please refer below.
https://introcs.cs.princeton.edu/java/11precedence/
Related
I want to ask about correct sequence "reading" of this logical expression:
(true && false | true)
I thought it returns false, because of first expression - true && false
But probably I'm doing something wrong and it's should be "reading" another way.
Can you explain what's correct way to reading it?
By keeping below the point in the notice:
All binary operators except for the assignment operators are evaluated from left to right; assignment operators are evaluated right to left.
This will be get executed from left to right. After that 2nd point to consider is Operator Precedence.
| is a bitwise operator and && is a logical operation. the bitwise operator has more priority than the logical operator.
In your case, the first evaluation will be false | true which is true.
then it will evaluate the true && result of above which is true.
so the given statement will be true.
Check the following table of Operators Precedence.
| (bitwise inclusive OR) has higher precedence than && (logical AND), so false | true is evaluated first.
That said, the evaluation order doesn't matter in your example. Both (true && false) | true and true && (false | true) return true. In the first case it's false | true), which is true. In the second case it's true && true, which is also true.
Now, here's an example where the operator precedence makes a difference:
System.out.println (false && true | true);
System.out.println (false && true || true);
| has a higher precedence than &&, but && has a higher precedence than ||.
Therefore these expressions are evaluated as:
System.out.println (false && (true | true));
System.out.println ((false && true) || true);
As a result, the first returns false and the second returns true.
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)
Why this boolean statement is true?
a= 10;
b = 0;
7 < a || a == b && b > 9 - a / b
Since anything divided by 0 is error
Since the first operand of the OR (||) operator (a > 7) evaluates to true, it short circuits and nothing else is evaluated. Therefore the entire expression evaluates to true.
7 < a returns true. Since it's a || after, the rest isn't executed.
This is because true || false is true, and true || true is true too, so evaluing the second member is but a waste of time.
Your OR-Operator || uses lazy evaluation or short-circuit evaluation. This means, since the very first expression 7 < ais true, it won't evaluate any other statements including the one with a division by zero, since java already found something true.
If you actually want to get an error, you can use this OR-Operator | which should enforce the evaluation of all statements. Most only use it as a bitwise-operator, but its also a non-short-circuit version of ||. For a more in-depth look at || vs. |, look here.
For example,
boolean c = (7 < a | a == b && b > 9 - a / b);
will cause an ArithmeticExcption, as expected.
When running the following program:
int i = 0;
boolean t = true;
boolean f = false, b;
b = (t || ((i++) == 0));
b = (f || ((i+=2) > 0));
System.out.println(i);
the answer is 2. Why?
In an OR statement in Java the left side is evaluated first and if it appears to be true the right side of the statement is considered not important, so Java doesn't check that side.
So in your case the i++ in de right side of the statement is not being called because t is true.
What's hapenning is due to the fact that the conditional-or operator || is short-circuiting (emphasis mine):
The conditional-or operator || operator is like | (§15.22.2), but evaluates its right-hand operand only if the value of its left-hand operand is false.
b = (t || ((i++) == 0));
In this line, t is true so the right-hand operand is not evaluated and the result is true. After this step, i is still 0.
b = (f || ((i+=2) > 0));
In this case, however, f is false so the right-hand operand is evaluated. This operand, among other things, evaluates i+=2 so i, which was 0 becomes 2 at the end of the evaluation.
Let's do it step by step.
b = (t || ((i++) == 0));
t evaluates to true and you have operator ||, which means that the JVM won't execute the second part - true || false == true and true || true == true, which means that the second part doesn't matter
b = (f || ((i+=2) > 0));
Now f evaluates to false. This time the VM doesn't know the answer of the expression, since it depends on the second one, so it evaluates (i+=2) > 0; Hence i becomes 2
Very simple
1. int i = 0;
2. boolean t = true;
3. boolean f = false, b;
4. b = (t || ((i++) == 0));
5. b = (f || ((i+=2) > 0));
6. System.out.println(i);
Line 1. i is 0
line 2. t is true
line 3. f is false, b is boolean
line 4. since t is true so || doesn't evaluate the part of (i++==0) even if it is false
line 5. f is false so here (i+=2)>0 is evaluated bcoz || evaluates util it get at least one true
line 6. i is 2 due to line 5
Note: if | is used in place of || so all parts are evaluated
|| matches the first true to return true for all
| matches all parts but needs at least one true
I always thought that && operator in Java is used for verifying whether both its boolean operands are true, and the & operator is used to do Bit-wise operations on two integer types.
Recently I came to know that & operator can also be used verify whether both its boolean operands are true, the only difference being that it checks the RHS operand even if the LHS operand is false.
Is the & operator in Java internally overloaded? Or is there some other concept behind this?
& <-- verifies both operands
&& <-- stops evaluating if the first operand evaluates to false since the result will be false
(x != 0) & (1/x > 1) <-- this means evaluate (x != 0) then evaluate (1/x > 1) then do the &. the problem is that for x=0 this will throw an exception.
(x != 0) && (1/x > 1) <-- this means evaluate (x != 0) and only if this is true then evaluate (1/x > 1) so if you have x=0 then this is perfectly safe and won't throw any exception if (x != 0) evaluates to false the whole thing directly evaluates to false without evaluating the (1/x > 1).
EDIT:
exprA | exprB <-- this means evaluate exprA then evaluate exprB then do the |.
exprA || exprB <-- this means evaluate exprA and only if this is false then evaluate exprB and do the ||.
Besides not being a lazy evaluator by evaluating both operands, I think the main characteristics of bitwise operators compare each bytes of operands like in the following example:
int a = 4;
int b = 7;
System.out.println(a & b); // prints 4
//meaning in an 32 bit system
// 00000000 00000000 00000000 00000100
// 00000000 00000000 00000000 00000111
// ===================================
// 00000000 00000000 00000000 00000100
boolean a, b;
Operation Meaning Note
--------- ------- ----
a && b logical AND short-circuiting
a || b logical OR short-circuiting
a & b boolean logical AND not short-circuiting
a | b boolean logical OR not short-circuiting
a ^ b boolean logical exclusive OR
!a logical NOT
short-circuiting (x != 0) && (1/x > 1) SAFE
not short-circuiting (x != 0) & (1/x > 1) NOT SAFE
It depends on the type of the arguments...
For integer arguments, the single ampersand ("&")is the "bit-wise AND" operator. The double ampersand ("&&") is not defined for anything but two boolean arguments.
For boolean arguments, the single ampersand constitutes the (unconditional) "logical AND" operator while the double ampersand ("&&") is the "conditional logical AND" operator. That is to say that the single ampersand always evaluates both arguments whereas the double ampersand will only evaluate the second argument if the first argument is true.
For all other argument types and combinations, a compile-time error should occur.
&& is a short circuit operator whereas & is a AND operator.
Try this.
String s = null;
boolean b = false & s.isEmpty(); // NullPointerException
boolean sb = false && s.isEmpty(); // sb is false
I think my answer can be more understandable:
There are two differences between & and &&.
If they use as logical AND
& and && can be logical AND, when the & or && left and right expression result all is true, the whole operation result can be true.
when & and && as logical AND, there is a difference:
when use && as logical AND, if the left expression result is false, the right expression will not execute.
Take the example :
String str = null;
if(str!=null && !str.equals("")){ // the right expression will not execute
}
If using &:
String str = null;
if(str!=null & !str.equals("")){ // the right expression will execute, and throw the NullPointerException
}
An other more example:
int x = 0;
int y = 2;
if(x==0 & ++y>2){
System.out.print(“y=”+y); // print is: y=3
}
int x = 0;
int y = 2;
if(x==0 && ++y>2){
System.out.print(“y=”+y); // print is: y=2
}
& can be used as bit operator
& can be used as Bitwise AND operator, && can not.
The bitwise AND " &" operator produces 1 if and only if both of the bits in
its operands are 1. However, if both of the bits are 0 or both of the bits are different then this operator produces 0. To be more precise bitwise AND " &" operator returns 1 if any of the two bits is 1 and it returns 0 if any of the bits is 0.
From the wiki page:
http://www.roseindia.net/java/master-java/java-bitwise-and.shtml
it's as specified in the JLS (15.22.2):
When both operands of a &, ^, or | operator are of type boolean or Boolean, then the type of the bitwise operator expression is boolean. In all cases, the operands are subject to unboxing conversion (§5.1.8) as necessary.
For &, the result value is true if both operand values are true; otherwise, the result is false.
For ^, the result value is true if the operand values are different; otherwise, the result is false.
For |, the result value is false if both operand values are false; otherwise, the result is true.
The "trick" is that & is an Integer Bitwise Operator as well as an Boolean Logical Operator. So why not, seeing this as an example for operator overloading is reasonable.
‘&&’ : - is a Logical AND operator produce a boolean value of true or false based on the logical relationship of its arguments.
For example: - Condition1 && Condition2
If Condition1 is false, then (Condition1 && Condition2) will always be false, that is the reason why this logical operator is also known as Short Circuit Operator because it does not evaluate another condition. If Condition1 is false , then there is no need to evaluate Condtiton2.
If Condition1 is true, then Condition2 is evaluated, if it is true then overall result will be true else it will be false.
‘&’ : - is a Bitwise AND Operator. It produces a one (1) in the output if both the input bits are one. Otherwise it produces zero (0).
For example:-
int a=12; // binary representation of 12 is 1100
int b=6; // binary representation of 6 is 0110
int c=(a & b); // binary representation of (12 & 6) is 0100
The value of c is 4.
for reference , refer this http://techno-terminal.blogspot.in/2015/11/difference-between-operator-and-operator.html
&& and || are called short circuit operators. When they are used, for || - if the first operand evaluates to true, then the rest of the operands are not evaluated. For && - if the first operand evaluates to false, the rest of them don't get evaluated at all.
so if (a || (++x > 0)) in this example the variable x won't get incremented if a was true.
With booleans, there is no output difference between the two. You can swap && and & or || and | and it will never change the result of your expression.
The difference lies behind the scene where the information is being processed. When you right an expression "(a != 0) & ( b != 0)" for a= 0 and b = 1, The following happens:
left side: a != 0 --> false
right side: b 1= 0 --> true
left side and right side are both true? --> false
expression returns false
When you write an expression (a != 0) && ( b != 0) when a= 0 and b = 1, the following happens:
a != 0 -->false
expression returns false
Less steps, less processing, better coding, especially when doing many boolean expression or complicated arguments.
Besides && and || being short circuiting, also consider operator precedence when mixing the two forms.
I think it will not be immediately apparent to everybody that result1 and result2 contain different values.
boolean a = true;
boolean b = false;
boolean c = false;
boolean result1 = a || b && c; //is true; evaluated as a || (b && c)
boolean result2 = a | b && c; //is false; evaluated as (a | b) && c
& is a bitwise operator plus used for checking both conditions because sometimes we need to evaluate both condition.
But && logical operator go to 2nd condition when first condition give true.
all answers are great, and it seems that no more answer is needed
but I just wonted to point out something about && operator called dependent condition
In expressions using operator &&, a condition—we’ll call this the dependent condition—may require another condition to be true for the evaluation of the dependent condition to be meaningful.
In this case, the dependent condition should be placed after the && operator to prevent errors.
Consider the expression (i != 0) && (10 / i == 2). The dependent condition (10 / i == 2) must appear after the && operator to prevent the possibility of division by zero.
another example (myObject != null) && (myObject.getValue() == somevaluse)
and another thing: && and || are called short-circuit evaluation because the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression
References: Java™ How To Program (Early Objects), Tenth Edition
In respect of the AND and OR operators, Java has got two types of evaluation namely Short-Circuit evaluation and full evaluation.
&& || Short-Circuit Evaluation
Short-Circuit evaluation enables you to not evaluate the right-hand side of AND and OR expressions, when the overall result can be predicted from the left-side value.
int numberOne = 1;
int numberTwo = 2;
boolean result = false;
// left-side is false so the the overall result CAN be predicted without evaluating the right side.
// numberOne will be 1, numberTwo will be 2, result will be false
result = (numberOne > numberTwo) && (++numberOne == numberTwo);
System.out.println(numberOne); // prints 1
System.out.println(numberTwo); // prints 2
System.out.println(result); // prints false
// left-side is true so the the overall result CAN NOT be predicted without evaluating the right side.
// numberOne will be 2, numberTwo will be 2, result will be true
result = (numberTwo > numberOne) && (++numberOne == numberTwo);
System.out.println(numberOne); // prints 2
System.out.println(numberTwo); // prints 2
System.out.println(result); // prints true
& | ^ Full Evaluation
Although in some cases it is possible to predict the result, It is necessary to evaluate the right-hand side.
int numberOne = 1;
int numberTwo = 2;
boolean result = false;
// left-side is false so the the overall result will be false BUT the right side MUST be evaluated too.
// numberOne will be 2, numberTwo will be 2, result will be false
result = (numberOne > numberTwo) & (++numberOne == numberTwo);
System.out.println(numberOne); // prints 2
System.out.println(numberTwo); // prints 2
System.out.println(result); // prints false
Notice:
Notice that for XOR (^) there is no short-circuit, because both sides are always required to determine the overall result.
Notice that other possible names for Short-Circuit evaluation are minimal evaluation and McCarthy evaluation.
It is not recommenced to mix boolean logic and actions in the same expression
& can also act as a Bitwise AND operator which is very academic and can be used in cryptography. When both bits are 1, the result is 1, or either of the bits is not 1, the result is 0. (Check the following code)
AND Bitwise example:
byte a = 5; // 00000101
byte b = 3; // 00000011
byte c = (byte) (a & b); // 00000001 (c is 1)
Almost every point of comparison is very well covered in all the answers. I just want to add one example. To demonstrate how the output changes based on which operator we use. Consider the below example
int a = 10;
if(++a==10 & ++a==12) {
++a;
}
System.out.println(a); //12
In the above code, We are using bitwise & operator. So It will evaluate both the arguments(left and right) irrespective of the individual result.
so a will increment 2 times within if condition. But as the condition will not become true, It will not enter inside the if-loop and 3rd increment will not happen. So the final value of a would become 12 in this case.
Now suppose, in the same above example If we use short-circuit && operator. then after evaluating ++a==10 to false, It will not go to check the second argument. And Hence the final value of a would-be 11.
int a = 10;
if(++a==10 && ++a==12) {
++a;
}
System.out.println(a); //11
Based on this, We can say that performance of bitwise & operator is relatively low compare to the short-circuit && operator. As bitwise operator will go to evaluate both the arguments irrespective of the result of the first argument. While && operator will stop evaluating the second argument if the first argument's result is false.
One more difference between these two is, Bitwise & operator is applicable for boolean as well as integral types. While short-circuit && operator is applicable only for the boolean type.
We can write
System.out.println(4 & 5); // 4
But if We try to write like ,
System.out.println(4 && 5);
Then it will give an error saying,
bad operand types for binary operator '&&'