Explain short-circuit evaluation with && and ||, and give a practical reason it matters.
answer
- false && X → false (skip X); true || X → true (skip X)
- Left evaluated first, always left-to-right
- Null-guard pattern: obj != null && obj.method()
- Skipped operand's side effects never run
- Order operands: cheap/guarding check first
basics
~20 sWith && and ||, Java checks the left side first and skips the right side if the answer is already known. false && X stays false without running X; true || X stays true without running X. This lets you safely null-check before using a value.
solid answer
~50 sShort-circuit evaluation means && and || evaluate their left operand first and only evaluate the right operand when the outcome is still undecided. For &&, a false left operand makes the whole expression false, so the right operand is skipped. For ||, a true left operand makes it true, so the right is skipped. The practical payoff is twofold: performance (skip expensive work) and, more importantly, safety — you can guard a potentially failing call. The classic pattern is `if (obj != null && obj.isValid())`: if obj is null, the right side never runs, avoiding a NullPointerException. The order of operands therefore becomes meaningful: put the cheaper or guarding check first. A subtle consequence is that side effects in the skipped operand (assignments, method calls, increments) simply do not happen, which can surprise people who rely on them.
code
java · 16 linesString name = null;
// SAFE: short-circuit skips length() when name is null
if (name != null && name.length() > 0) {
System.out.println("non-empty");
}
// WOULD THROW NPE if reordered:
// if (name.length() > 0 && name != null) { ... }
int[] counter = {0};
java.util.function.BooleanSupplier f = () -> { counter[0]++; return true; };
boolean a = false && f.getAsBoolean(); // f skipped; counter stays 0
boolean b = true || f.getAsBoolean(); // f skipped; counter stays 0
System.out.println(counter[0]); // prints 0go deeper
Can explain false&&X / true||X skip the right side and use the obj != null && obj.method() guard.
Understands side effects in the skipped operand don't run and orders operands deliberately for safety and speed.
Reasons about operand ordering for performance hot paths and explains why relying on skipped side effects is a code smell; contrasts with & / |.
Codifies null-guard and operand-ordering conventions, spots short-circuit-dependent side effects in review, and considers readability vs. micro-optimization trade-offs across a codebase.
## The core idea **Short-circuit evaluation** (also called *lazy* or *minimal* evaluation) means Java stops evaluating a logical expression as soon as the final result is certain. It applies to the two short-circuiting operators `&&` and `||`. Think about how the truth tables behave: - For **`A && B`** (AND): if `A` is `false`, the result is `false` no matter what `B` is. So Java doesn't bother computing `B`. - For **`A || B`** (OR): if `A` is `true`, the result is `true` no matter what `B` is. So Java doesn't bother computing `B`. Java **always evaluates the left operand first**, then decides whether the right operand is needed. ## Why this matters #1 — null-safety guards The most important everyday use is guarding against errors. A **NullPointerException (NPE)** happens when you call a method on a `null` reference. Consider: ```java if (user != null && user.isActive()) { ... } ``` If `user` is `null`, the left operand `user != null` is `false`, so `&&` short-circuits and `user.isActive()` is never called — no NPE. If you wrote them in the wrong order, `user.isActive() && user != null`, you'd crash on a null `user`. **Operand order is part of the logic.** The OR mirror image: ```java if (input == null || input.isBlank()) { return; } ``` If `input` is `null`, the left is `true`, so `||` short-circuits and `input.isBlank()` is skipped — again no NPE. ## Why this matters #2 — performance / avoiding work Put cheap, likely-decisive checks first so expensive ones are skipped: ```java if (cache.contains(key) || database.lookup(key)) { ... } ``` If the in-memory `cache.contains(key)` is `true`, the costly `database.lookup(key)` is never executed. ## Why this matters #3 — side effects can be skipped A **side effect** is anything an expression does besides producing a value — printing, mutating a variable, incrementing a counter, calling a method that changes state. With short-circuiting, side effects in the skipped operand **do not run**: ```java int calls = 0; boolean f() { calls++; return true; } boolean r = false && f(); // f() is skipped; calls stays 0 boolean s = true || f(); // f() is skipped; calls stays 0 ``` This is a frequent source of subtle bugs when someone relies on the right-hand side always running. ## Contrast with non-short-circuiting & and | Java also has `&` and `|`, which on booleans compute the same AND/OR but **always evaluate both operands** (no short-circuit). That difference is its own topic, but the headline is: use `&&`/`||` in conditions; reserve `&`/`|` for the rare case you genuinely want both sides evaluated (or for bitwise math on integers). ## Mental model Read `&&` as "and, but only check the right if the left was true"; read `||` as "or, but only check the right if the left was false". The expression is evaluated **left to right**, and evaluation stops the instant the answer is locked in.
- Why must the null check come before the method call in obj != null && obj.method()?Because evaluation is left-to-right and only short-circuits after the left side. If you put the call first and obj is null, it runs immediately and throws an NPE before the null check is ever reached.
- Does short-circuiting change the boolean result compared to evaluating both sides?No — the final boolean value is identical to a full evaluation. Only whether the right operand is executed (and its side effects) differs.
It's like a checklist where you stop early. To enter a building you need keycard AND PIN (&&) — if your keycard fails, the guard doesn't even ask for the PIN. To win a prize you need a winning ticket OR a coupon (||) — if your ticket already wins, nobody checks the coupon.
saying these in an interview costs you the question
- Saying short-circuiting changes the truth value — it only changes whether the right side runs
- Relying on a side effect in the right operand that gets skipped
- Putting the method call before the null check and assuming it's safe
- Thinking evaluation can go right-to-left