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

OperatorOperates onShort-circuits?Typical use
||booleanYesconditions, validation
|boolean OR int bitsNoflags, 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

ABA || B
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

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 | with OR (SQL) or or (Python). Java has no or keyword.

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.