Skip to content

Lesson 03 · Boolean & Conditions

Objectives

After this lesson you will be able to:

  • Distinguish the boolean primitive from the Boolean wrapper, and parse booleans safely.
  • Tell short-circuit (&&, ||) from eager bitwise (&, |, ^) boolean operators and predict which side-effects run.
  • Use the ternary operator and read its precedence correctly.
  • Avoid the classic boolean traps: assignment-vs-equality, null-unboxing, and operator precedence.

boolean vs Boolean

boolean is one of the eight primitives — it holds exactly true or false (Java has no truthiness: 0, "", and null are not booleans, and if (1) does not compile). Boolean is its immutable wrapper in java.lang.

java
boolean b = true;
Boolean w = b;            // autobox
boolean back = w;         // unbox — NPE if w is null

Boolean.parseBoolean is lenient and case-insensitive: it returns true only for "true" (any case) and false for everything else, including null — it never throws.

java
Boolean.parseBoolean("TRUE");   // true
Boolean.parseBoolean("yes");    // false  (not the word "true")
Boolean.parseBoolean(null);     // false  (no exception)

Exam trap

Unboxing a null Boolean in a condition throws NullPointerException:

java
Boolean flag = null;
if (flag) { }            // NPE — unboxes null to boolean

Logical operators: short-circuit vs bitwise

&& and || are short-circuit: they stop as soon as the result is known, so the right operand may never run. &, |, and ^ applied to booleans are eager — they always evaluate both sides.

java
boolean a = false, b = true;
a && expensive();        // expensive() is skipped (a is false)
a &  expensive();        // expensive() still runs (eager)
b || expensive();        // expensive() is skipped (b is true)
b |  expensive();        // expensive() still runs (eager)
a ^ b;                   // exclusive-or: true (exactly one is true)

Exam trap

The eager forms run side-effects you may not expect. Watch increments hidden on the right side:

java
int i = 0;
boolean r1 = (false && (i++ > 0));   // i stays 0  (short-circuit skips i++)
boolean r2 = (false &  (i++ > 0));   // i becomes 1 (eager evaluates i++)

Short-circuiting is also the idiom for null-guarding:

java
if (s != null && s.length() > 0) { }   // safe: length() only runs when s != null
if (s != null & s.length() > 0)  { }   // NPE risk: right side always runs

The ternary operator

condition ? whenTrue : whenFalse is Java's only ternary operator and the only operator that is an expression yielding a value. Both result branches must be assignment-compatible with a common type.

java
int max = (a > b) ? a : b;
String label = n == 1 ? "item" : "items";

Gotcha

The ternary has very low precedence — lower than arithmetic, so ?: binds last:

java
int x = 5;
String s = "v=" + x > 3 ? "hi" : "lo";   // does NOT compile
// + binds first: ("v=" + x) is a String, then String > 3 is illegal.
String t = "v=" + (x > 3 ? "hi" : "lo"); // parenthesize the ternary

Recall from Lesson 02 that mixing numeric wrapper types in the two branches triggers binary numeric promotiontrue ? 1 : 2.0 is the double 1.0, not int 1.

= vs ==

= assigns; == compares. Because an assignment expression has a value, a stray = can compile when the left side is a boolean:

java
boolean done = false;
if (done = true) { }     // compiles! assigns true, then tests true — always enters
if (done == true) { }    // comparison (and `if (done)` is cleaner still)

SDET note

Prefer if (done) / if (!done) over == true / == false — it is shorter and removes the =/== foot-gun entirely. In assertions, assert the boolean directly (assertTrue(done)) rather than assertEquals(true, done).

Key Takeaways

  • boolean holds only true/false; there is no truthiness and no if (int). Boolean is the wrapper — unboxing null in a condition is an NPE.
  • Boolean.parseBoolean is case-insensitive, returns true only for "true", false for anything else (including null), and never throws.
  • &&/|| short-circuit (right side may be skipped); &/|/^ on booleans are eager (both sides always run) — this matters for side-effects and null-guards.
  • The ternary ?: is a value-producing expression with very low precedence; parenthesize it inside larger expressions, and mind numeric promotion across its branches.
  • if (b = true) compiles and is almost always a bug — write if (b).

Lesson Quiz

Lesson Quiz · Boolean & Conditions0 / 6
  1. What does Boolean.parseBoolean("Yes") return?

    • Atrue
    • Bfalse
    • CNullPointerException
    • DCompile error
  2. What is the value of i afterward?

    int i = 0;
    boolean r = (false & (i++ > 0));
    • A0
    • B1
    • CCompile error
    • DNullPointerException
  3. What happens at runtime?

    Boolean flag = null;
    if (flag) { System.out.println("hi"); }
    • APrints hi
    • BPrints nothing
    • CNullPointerException
    • DCompile error
  4. Which expression compiles and assigns "hi"?

    int x = 5;
    • AString s = "v=" + x > 3 ? "hi" : "lo";
    • BString s = "v=" + (x > 3 ? "hi" : "lo");
    • CString s = x > 3 ? "hi" : "lo" + "v=";
    • DBoth A and B
  5. What does this print?

    boolean done = false;
    if (done = true) System.out.println("in");
    else System.out.println("out");
    • Ain
    • Bout
    • CCompile error
    • DNothing
  6. What is true ^ true ?

    • Atrue
    • Bfalse
    • CCompile error
    • D1

Next: Dates & Times — the java.time API. Run the matching code in labs/src/main/java/com/jse21/m01_values/Booleans.java.