OR Operator in Java: Bitwise | vs Logical ||
Java has two distinct OR operators that look similar but behave very differently: logical OR (||) and bitwise OR (|). Confusing them is one of the most common sources of subtle bugs.
At a glance
| Operator | Operates on | Short-circuits? | Typical use |
|---|---|---|---|
|| | boolean | Yes | conditions, validation |
| | boolean OR int bits | No | flags, bit masks |
Logical OR (||)
The canonical condition operator. Returns true if either operand is true.
boolean isAdmin = true;
boolean isEditor = false;
if (isAdmin || isEditor) {
System.out.println("Allowed");
}
Short-circuit evaluation
If the left operand is true, Java does not evaluate the right operand β the result is already determined. This is essential when the right side could throw an exception:
if (obj == null || obj.isEmpty()) {
// Safe: if obj is null, obj.isEmpty() is never called
}
if (obj.isEmpty() || obj == null) {
// β If obj is null, NullPointerException
}
Truth table
| A | B | A || B |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
Bitwise OR (|)
On int or long, | performs a bit-by-bit OR. Each bit in the result is 1 if the corresponding bit is 1 in either operand.
int a = 0b1100; // 12
int b = 0b1010; // 10
int c = a | b; // 0b1110 = 14
System.out.println(c); // 14
Common use: flags
Bitwise OR combines flags into a single int:
static final int READ = 1 << 0; // 0b0001
static final int WRITE = 1 << 1; // 0b0010
static final int EXECUTE = 1 << 2; // 0b0100
int permissions = READ | WRITE; // 0b0011
boolean canRead = (permissions & READ) != 0; // true
Bitwise OR on booleans
| also works with boolean, but does not short-circuit β both sides are always evaluated.
boolean a = expensiveCheck();
boolean b = otherCheck();
boolean result = a | b; // both calls run, even if a is already true
This is sometimes desired β for example, if both calls have side effects that must run regardless.
|| vs | β choose correctly
// β
Control flow / conditions β use ||
if (user == null || user.isBanned()) { ... }
// β
Bit flags / bit manipulation β use |
int flags = FLAG_A | FLAG_B | FLAG_C;
// β Booleans, but want both sides to always run β |
boolean a = log("left") | log("right"); // both execute
boolean b = log("left") || log("right"); // right may be skipped
Compound assignment (|=)
The |= operator updates the left side with the OR of both operands.
int flags = 0;
flags |= READ; // add READ to flags
flags |= WRITE; // add WRITE
// flags == 0b11
Operator precedence
Both | and || have lower precedence than arithmetic and comparison operators, but | binds tighter than ||. Parenthesize when mixing to keep intent clear:
if (a == 1 || b == 2 && c == 3) { ... }
// Parses as: a == 1 || (b == 2 && c == 3)
if ((a | b) == 0xFF) { ... } // parentheses explicit
Common mistakes
- Writing
|in a condition where you meant||: both work for booleans, but|forces evaluation of both sides β NPE risk. - Writing
||for bit flags: won't compile (||requires booleans). - Confusing
|withOR(SQL) oror(Python). Java has noorkeyword.
Quick reference
- Condition β
|| - Bit flag β
| - Both with side effects β
|(on booleans) - Null-safe chain β
||(short-circuits)
Master these two operators and most boolean logic and bit manipulation become second nature.