skip to content

What is the difference between && / || and the boolean & / | operators in Java?

level: middleimportance: should knowfreq 65%

answer

  1. && / || short-circuit; & / | always evaluate both
  2. Same boolean RESULT, different EVALUATION
  3. & / | on ints = bitwise; && / || ints = illegal
  4. & / | bind tighter than && / || — parenthesize
  5. No short-circuit version exists for bitwise math

basics

~20 s

&& and || stop early (short-circuit): they skip the right side once the answer is known. & and | on booleans give the same true/false result but always evaluate BOTH sides. On integers, & and | are bitwise operators instead.

solid answer

~40 s

When both operands are boolean, `&&`/`&` compute logical AND and `||`/`|` compute logical OR, producing the same boolean result. The difference is evaluation: `&&` and `||` short-circuit (skip the right operand when the result is already determined), while `&` and `|` are non-short-circuiting — they always evaluate both operands. So if the right operand has a side effect or could throw, the choice matters. In practice you almost always want `&&`/`||` in conditions, both for null-safety and to avoid needless work. You'd deliberately use `&`/`|` only when you truly need both sides evaluated (e.g. both have required side effects). Note that `&`/`|` are overloaded: on integral types they are bitwise operators, and `&`/`|` also bind tighter than `&&`/`||`, which can surprise you in mixed expressions. There's no `&&`/`||` equivalent for bitwise math.

code

java · 12 lines
java
boolean log(String s) { System.out.println(s); return true; }

boolean a = false && log("&&");  // prints nothing (short-circuit)
boolean b = false &  log("&");   // prints "&"   (always evaluated)

// bitwise meaning on integers:
int x = 6 & 3;   // 0110 & 0011 = 0010 = 2
int y = 6 | 3;   // 0110 | 0011 = 0111 = 7

// precedence: parsed as p || (q & r)
boolean p = false, q = true, r = false;
boolean res = p || q & r;  // false || (true & false) = false

go deeper

for a junior

Knows & / | exist and that &&/|| are the usual ones; may not yet articulate the non-short-circuit distinction.

for a middle

Clearly explains same-result-but-both-sides-evaluated, the null-guard implication, and the dual bitwise meaning on integers.

for a senior

Knows the precedence ordering (& > ^ > |, all above &&/||), gives the legitimate 'evaluate both for side effects' use case, and prefers clearer alternatives.

for a principal

Guides when (rarely) & on booleans is acceptable vs. refactoring to explicit statements; flags mixed bitwise/logical precedence hazards in shared code.

## Two families that overlap on booleans Java reuses the symbols `&` and `|` for two different jobs depending on operand type: 1. **Bitwise operators** when operands are integral (`int`, `long`, etc.): they combine the individual bits of the numbers. `6 & 3` is `2`, `6 | 3` is `7`. 2. **Boolean logical operators** when both operands are `boolean`: `&` is logical AND, `|` is logical OR. Meanwhile `&&` and `||` are **only** for booleans and have no bitwise meaning. ## The key difference: short-circuiting For two boolean operands, `a && b` and `a & b` produce the **same true/false answer**, and so do `a || b` and `a | b`. The difference is **whether the right operand is always evaluated**: - **`&&` / `||` short-circuit.** They evaluate the left operand, and only evaluate the right if the result isn't already decided (`false && x` skips `x`; `true || x` skips `x`). - **`&` / `|` do NOT short-circuit.** They **always** evaluate both operands, even when the left already determines the answer. ```java boolean f() { System.out.println("f called"); return true; } boolean a = false && f(); // prints nothing — f() skipped boolean b = false & f(); // prints "f called" — f() always runs ``` ## Why short-circuiting is usually what you want Because `&` / `|` always run the right operand, you **lose** the null-guard safety: ```java if (obj != null & obj.isValid()) { ... } // BUG: obj.isValid() runs even when obj is null → NPE if (obj != null && obj.isValid()) { ... } // SAFE ``` So in conditions, prefer `&&` / `||` by default. ## When you might choose & or | The legitimate reason to use `&` / `|` on booleans is when you **want both sides evaluated for their side effects**, regardless of the outcome: ```java // run BOTH validators and collect all errors, even if the first fails boolean ok = validateName(form) & validateEmail(form); ``` With `&&`, a failing `validateName` would skip `validateEmail` and you'd miss its error. This is a niche but real pattern — though many teams prefer to make the intent explicit with separate statements. ## Precedence trap `&` and `|` bind **tighter** than `&&` and `||` (and tighter than each other: `&` > `^` > `|`). In a mixed expression that can change grouping: ```java // parsed as: a || (b & c) — not (a || b) & c boolean r = a || b & c; ``` When mixing, add parentheses. ## There's no short-circuit bitwise operator Short-circuiting only makes sense for booleans (where the left can determine the whole result). Bit math always needs all bits, so Java provides no `&&`/`||` for integers — only `&`, `|`, `^`. ## Quick decision guide - Condition with a guard or expensive right side → `&&` / `||`. - Need both boolean sides' side effects → `&` / `|` (or, clearer, two statements). - Manipulating bits of an integer → `&` / `|` / `^` (bitwise).

  • Is there a performance reason to prefer & over &&?
    Almost never. && avoids evaluating the right operand when possible, so if anything it's cheaper. & is chosen for semantics (force both sides), not speed.
  • What does 6 & 3 evaluate to and why?
    2. In binary 6 is 0110 and 3 is 0011; bitwise AND keeps bits set in both, giving 0010 = 2.

&& is a careful interviewer who stops asking once they've decided no. & is a bureaucrat who fills out every form regardless — even when the application was already rejected, every box still gets ticked (the side effects still happen).

saying these in an interview costs you the question

  • Claiming & and && give different boolean results — they give the same result, only evaluation differs
  • Using & in a null-guard and assuming it's safe
  • Forgetting & / | bind tighter than && / || in mixed expressions
  • Thinking && works for bitwise integer math

context