In Java, the distinction between || (logical OR) and | (bitwise OR) goes beyond syntax—it fundamentally affects evaluation order, side effects, and performance. Understanding when each operator evaluates its right-hand operand is essential for writing predictable, safe, and efficient code.
Key Differences
- Logical OR (
||): A short-circuit operator. If the left operand evaluates totrue, the right operand is not evaluated. This prevents unnecessary computation and avoids potential exceptions or side effects. - Bitwise OR (
|): Always evaluates both operands—regardless of the left operand’s value. When used with booleans, it behaves as a non-short-circuit logical OR; when used with integers, it performs bit-level disjunction.
Practical Code Examples
1. Short-Circuit Safety with ||
public class SafeOrCheck {
public static void main(String[] args) {
String input = null;
boolean isValid = (input != null) && !input.trim().isEmpty(); // Safe due to && short-circuit
boolean isEitherValid = (input != null) || input.length() > 0; // ❌ Throws NullPointerException
// Correct usage with || — left condition guards the right
boolean safeOr = (input != null) && (input.length() > 0) || "default".length() > 0;
System.out.println("Safe OR result: " + safeOr); // true
}
}
2. Forced Eavluation with |
public class ForcedEvaluationDemo {
private static int counter = 0;
private static boolean incrementAndReturn() {
counter++;
return false;
}
public static void main(String[] args) {
counter = 0;
boolean result1 = incrementAndReturn() || incrementAndReturn();
System.out.println("Short-circuit || count: " + counter); // prints 1
counter = 0;
boolean result2 = incrementAndReturn() | incrementAndReturn();
System.out.println("Non-short-circuit | count: " + counter); // prints 2
}
}
Evaluation Precedence in Expressions
Both operators follow left-to-right associativity, but || has lower precedence than &&, which in turn is lower than relational operaotrs like == or <. Parentheses are recommended for clarity in complex conditions:
boolean outcome = (x > 0) || (y < 5 && z != null) | (flag); // Avoid mixing | and || without grouping
Better practice:
boolean outcome = (x > 0) || ((y < 5 && z != null) || flag); // Use || consistently for booleans
When to Use Which?
- Use
||for conditional logic involving method calls, null checks, or expensive operations. - Use
|only when you explicitly require both sides to execute (e.g., side-effect accumulation) or when performing integer bitwise operations. - Never use
|for booleen logic unless intentional non-short-circuiting is required—and document that intent clearly.