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 &&
.
| 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.
Logical
||
and&&
check the right hand side only if necessary. The|
and&
check both the sides everytime.For example:
Rewrite it:
Another example:
Rewrite it:
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.If you use the
||
and&&
forms, rather than the|
and&
forms of these operators, Java will not bother to evaluate the right-hand operand alone.It's a matter of if you want to short-circuit the evaluation or not -- most of the time you want to.
A good way to illustrate the benefits of short-circuiting would be to consider the following example.
Another benefit, as Jeremy and Peter mentioned, for short-circuiting is the null reference check:
more info