I'm just wondering why we usually use logical OR ||
between two booleans not bitwise OR |
, though they are both working well.
I mean, look at the following:
if(true | true) // pass
if(true | false) // pass
if(false | true) // pass
if(false | false) // no pass
if(true || true) // pass
if(true || false) // pass
if(false || true) // pass
if(false || false) // no pass
Can we use |
instead of ||
? Same thing with &
and &&
.
Java operators
| is bitwise or, || is logical or.
In addition to short-circuiting, another thing to keep in mind is that doing a bitwise logic operation on values that can be other than 0 or 1 has a very different meaning than conditional logic. While it USUALLY is the same for
|
and||
, with&
and&&
you get very different results (e.g.2 & 4
is 0/false while2 && 4
is 1/true).If the thing you're getting from a function is actually an error code and you're testing for non-0-ness, this can matter quite a lot.
This isn't as much of an issue in Java where you have to explicitly typecast to boolean or compare with 0 or the like, but in other languages with similar syntax (C/C++ et al) it can be quite confusing.
Also, note that & and | can only apply to integer-type values, and not everything that can be equivalent to a boolean test. Again, in non-Java languages, there are quite a few things that can be used as a boolean with an implicit
!= 0
comparison (pointers, floats, objects with anoperator bool()
, etc.) and bitwise operators are almost always nonsensical in those contexts.The other answers have done a good job of covering the functional difference between the operators, but the answers could apply to just about every single C-derived language in existence today. The question is tagged with java, and so I will endeavor to answer specifically and technically for the Java language.
&
and|
can be either Integer Bitwise Operators, or Boolean Logical Operators. The syntax for the Bitwise and Logical Operators (§15.22) is:The syntax for
EqualityExpression
is defined in §15.21, which requiresRelationalExpression
defined in §15.20, which in turn requiresShiftExpression
andReferenceType
defined in §15.19 and §4.3, respectively.ShiftExpression
requiresAdditiveExpression
defined in §15.18, which continues to drill down, defining the basic arithmetic, unary operators, etc.ReferenceType
drills down into all the various ways to represent a type. (WhileReferenceType
does not include the primitive types, the definition of primitive types is ultimately required, as they may be the dimension type for an array, which is aReferenceType
.)The Bitwise and Logical Operators have the following properties:
The distinction between whether the operator serves as a bitwise operator or a logical operator depends on whether the operands are "convertible to a primitive integral type" (§4.2) or if they are of types
boolean
orBoolean
(§5.1.8).If the operands are integral types, binary numeric promotion (§5.6.2) is performed on both operands, leaving them both as either
long
s orint
s for the operation. The type of the operation will be the type of the (promoted) operands. At that point,&
will be bitwise AND,^
will be bitwise exclusive OR, and|
will be bitwise inclusive OR. (§15.22.1)If the operands are
boolean
orBoolean
, the operands will be subject to unboxing conversion if necessary (§5.1.8), and the type of the operation will beboolean
.&
will result intrue
if both operands aretrue
,^
will result intrue
if both operands are different, and|
will result intrue
if either operand istrue
. (§15.22.2)In contrast,
&&
is the "Conditional-And Operator" (§15.23) and||
is the "Conditional-Or Operator" (§15.24). Their syntax is defined as:&&
is like&
, except that it only evaluates the right operand if the left operand istrue
.||
is like|
, except that it only evaluates the right operand if the left operand isfalse
.Conditional-And has the following properties:
Conditional-Or has the following properties:
In short, as @JohnMeagher has repeatedly pointed out in the comments,
&
and|
are, in fact, non-short-circuiting boolean operators in the specific case of the operands being eitherboolean
orBoolean
. With good practices (ie: no secondary effects), this is a minor difference. When the operands aren'tboolean
s orBoolean
s, however, the operators behave very differently: bitwise and logical operations simply don't compare well at the high level of Java programming.When I had this question I created test code to get an idea about this.
In this case, we only change left side value of if condition adding a or b.
output
"If condition executed"
Output-
Conclusion of ||
When use||
, right side only check when the left side is false.Output-
Output-
Conclusion of |
When use|
, check both left and right side.| is a bitwise operator. || is a logical operator.
One will take two bits and or them.
One will determine truth (this OR that) If this is true or that is true, then the answer is true.
Oh, and dang people answer these questions fast.
So just to build on the other answers with an example, short-circuiting is crucial in the following defensive checks:
Using
|
and&
instead could result in aNullPointerException
being thrown here.