Shortcut or-assignment (|=) operator in Java
The |=
is a compound assignment operator (JLS 15.26.2) for the boolean logical operator |
(JLS 15.22.2); not to be confused with the conditional-or ||
(JLS 15.24). There are also &=
and ^=
corresponding to the compound assignment version of the boolean logical &
and ^
respectively.
In other words, for boolean b1, b2
, these two are equivalent:
b1 |= b2;
b1 = b1 | b2;
The difference between the logical operators (&
and |
) compared to their conditional counterparts (&&
and ||
) is that the former do not "shortcircuit"; the latter do. That is:
&
and|
always evaluate both operands&&
and||
evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:- The left operand of
&&
evaluates tofalse
- (because no matter what the right operand evaluates to, the entire expression is
false
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
||
evaluates totrue
- (because no matter what the right operand evaluates to, the entire expression is
true
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
So going back to your original question, yes, that construct is valid, and while |=
is not exactly an equivalent shortcut for =
and ||
, it does compute what you want. Since the right hand side of the |=
operator in your usage is a simple integer comparison operation, the fact that |
does not shortcircuit is insignificant.
There are cases, when shortcircuiting is desired, or even required, but your scenario is not one of them.
It is unfortunate that unlike some other languages, Java does not have &&=
and ||=
. This was discussed in the question Why doesn't Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=).
When should I not use the Java Shortcut Operator &
Well the reason for &
and &&
is not, that one evaluates the right side and the other doesn't.
&
is a bitwise operator, which makes a bitwise AND of the two values. It returns a value.Theoretically, if all bits of the left side are 0 (as is the case for
false
), the right side must not neccessarily be evaluated. I guess it's a design decision that it is evaluated in every case. In the simple cases, it is faster than checking if the left side is 0.&&
is a conditional logical operator, which takes two booleans and returns a boolean (that istrue
if and only if both sides aretrue
).The same applies here, if the left side is
false
, we don't need to check the right side. Here the decision was taken to skip the evaluation of the right side in that case.
And to answer your last question (when would you want to evaluate the RHS if the LHS has failed), there are some scenarios where it can be ok. However, in any case it is possible to prevent these situations (see jocelyn's answer for a good way to make sure that both expressions are evaluated) without loosing readability. In fact, I think jocelyn's way is more readable than if (exprA() & exprB()) { ... }
.
Personally I never use &
unless I really need a bitwise AND.
Java logical operator short-circuiting
The &&
and ||
operators "short-circuit", meaning they don't evaluate the right-hand side if it isn't necessary.
The &
and |
operators, when used as logical operators, always evaluate both sides.
There is only one case of short-circuiting for each operator, and they are:
false && ...
- it is not necessary to know what the right-hand side is because the result can only befalse
regardless of the value theretrue || ...
- it is not necessary to know what the right-hand side is because the result can only betrue
regardless of the value there
Let's compare the behaviour in a simple example:
public boolean longerThan(String input, int length) {
return input != null && input.length() > length;
}
public boolean longerThan(String input, int length) {
return input != null & input.length() > length;
}
The 2nd version uses the non-short-circuiting operator &
and will throw a NullPointerException
if input
is null
, but the 1st version will return false
without an exception.
Do &= and |= short-circuit in Java?
No, |=
and &=
do not shortcircuit, because they are the compound assignment version of &
and |
, which do not shortcircuit.
JLS 15.26.2 Compound Assignment Operators
A compound assignment expression of the form
E1 op= E2
is equivalent toE1 = (T)((E1) op (E2))
, whereT
is the type ofE1
, except thatE1
is evaluated only once.
Thus, assuming boolean &
, the equivalence for isFoobared &= methodWithSideEffects()
is:
isFoobared = isFoobared & methodWithSideEffects(); // no shortcircuit
On the other hand &&
and ||
do shortcircuit, but inexplicably Java does not have compound assignment version for them. That is, Java has neither &&=
nor ||=
.
See also
- Shortcut “or-assignment” (|=) operator in Java
- What’s the difference between | and || in Java?
- Why doesn’t Java have compound assignment versions of the conditional-and and conditional-or operators? (&&=, ||=)
What is this shortcircuiting business anyway?
The difference between the boolean
logical operators (&
and |
) compared to their boolean
conditional counterparts (&&
and ||
) is that the former do not "shortcircuit"; the latter do. That is, assuming no exception etc:
&
and|
always evaluate both operands&&
and||
evaluate the right operand conditionally; the right operand is evaluated only if its value could affect the result of the binary operation. That means that the right operand is NOT evaluated when:- The left operand of
&&
evaluates tofalse
- (because no matter what the right operand evaluates to, the entire expression is
false
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
||
evaluates totrue
- (because no matter what the right operand evaluates to, the entire expression is
true
)
- (because no matter what the right operand evaluates to, the entire expression is
- The left operand of
References
- JLS 15.22.2 Boolean Logical Operators
&
,^
, and|
- JLS 15.23 Conditional-And Operator
&&
- JLS 15.24 Conditional-Or Operator
||
What is the /= operator in Java?
It's a combination division-plus-assignment operator.
a /= b;
means divide a
by b
and put the result in a
.
There are similar operators for addition, subtraction, and multiplication: +=
, -=
and *=
.
%=
will do modulus.
>>=
and <<=
will do bit shifting.
What is difference between logical OR and short circuit OR operator?
The difference is that the short circuit operator doesn't evaluate the second operand if the first operand is true, which the logical OR without short circuit always evaluates both operands.
You wouldn't see any difference in your simple test, since both should give the same output assuming no exception is thrown, but if you try something like this :
String s = null;
System.out.println("a || b = " + s==null || s.length() == 0 );
System.out.println("a | b = " + s==null | s.length() == 0 );
The first operator will give you true, while the second operator will give you NullPointerException
, since only the |
operator will attempt to evaluate s.length() == 0
.
Short form for Java if statement
Use the ternary operator:
name = ((city.getName() == null) ? "N/A" : city.getName());
I think you have the conditions backwards - if it's null, you want the value to be "N/A".
What if city is null? Your code *hits the bed in that case. I'd add another check:
name = ((city == null) || (city.getName() == null) ? "N/A" : city.getName());
Related Topics
How to Convert a String to Another Locale
How to Call Subclasses' Methods on a Superclass Object
Why Equal Operator Works for Integer Value Until 128 Number
Where Is the Javabean Property Naming Convention Defined
<Form Action="/Sampleservlet" Giving Me Exception
How to Change the Dock Icon of a Java Program
Create a New Line in Java's Filewriter
How to Make Notepad to Save Text in Utf-8 Without the Bom
CSV Parsing in Java - Working Example
JSONobject:Why JSONobject Changing the Order of Attributes
Validate Jaxbelement in JPA/Jax-Rs Web Service
How to Use @Id with String Type in JPA/Hibernate
Use Custom Fonts When Creating PDF Using Ireport