Logical operators & short-circuit in Java
&& and || skip the right side; & and | always evaluate both.
s.length() on a null String crashes. Yet s != null && s.length() > 3 never does. How can the same call be safe on one side of &&?AND, OR, NOT, XOR
&& is true if both sides are true. || is true if at least one is. ! flips a boolean. ^ is true when exactly one side is true; on booleans it's the same as !=.
true && false // false
true || false // true
!true // false
true ^ false // trueShort-circuit
&& and || stop early when the left side already decides the answer. false && ... is false no matter what, so the right side is skipped. true || ... is true no matter what, so again the right side is skipped.
Your turn
s is null. What happens?
String s = null;
if (s != null && s.isEmpty()) {
System.out.println("empty");
} else {
System.out.println("no text");
}emptyno textThrows NullPointerException
Show the answer
s != null is false, so && never calls s.isEmpty(). The else branch prints no text. This is the standard null-guard pattern.
& and | never skip
On booleans, single & and | give the same true/false results as && and ||, but they always evaluate both sides. That's rarely what you want.
Your turn
Same guard, but with a single &. What happens?
String s = null;
boolean ok = s != null & s.isEmpty();
System.out.println(ok);falsetrueThrows NullPointerException
Show the answer
& evaluates both sides even though the left is already false, so s.isEmpty() runs on null: NullPointerException.
Side effects that never happen
Code on the right of && or || may never run. Here || skips ++n, while | runs it, so n ends up 1. Never hide important work, like saving data, on the right of a short-circuit.
int n = 0;
boolean a = true || ++n > 0; // skipped
boolean b = false | ++n > 0; // runs
// n is 1In real projects
Null guards are everywhere in production Java: user != null && user.isAdmin(), list != null && !list.isEmpty(). Swap && for & and the guard silently stops protecting you.
Key takeaways
- false && … → right side skipped
- true || … → right side skipped
- & and | evaluate both sides, always
- Guard pattern: s != null && s.isEmpty()
De Morgan's laws, from the 1800s, let you flip conditions: !(a && b) equals !a || !b, and !(a || b) equals !a && !b. Programmers use them to simplify tangled ifs.
Practice questions
What does this print?
String s = null;
if (s != null && s.length() > 3) {
System.out.println("long");
} else {
System.out.println("short or null");
}- long
- Throws NullPointerException
- Compile error
- short or null
Check your answer
short or null. s != null is false, so && skips s.length() entirely. This is the standard null-guard pattern.
What does this print?
String s = null;
boolean ok = s != null & s.length() > 3;
System.out.println(ok);- false
- true
- Compile error
- Throws NullPointerException
Check your answer
Throws NullPointerException. & is not short-circuit: it evaluates both sides even though the left is false, so s.length() runs on null.