Boolean Logic

There is no “truthy”

A condition must be a boolean. Nothing else.

if (text) {  }              // error
if (!text.isEmpty()) {  }   // ok

if (count) {  }             // error
if (count != 0) {  }        // ok

Comparison

Operator Meaning
== != equal / not equal (identity for objects)
< > <= >= ordering
a.equals(b)              // content comparison
Objects.equals(a, b)     // null-safe on both sides

The wrapper trap — small values are cached:

Integer x = 127, y = 127;
Integer p = 128, q = 128;

x == y        // true  (cache −128…127)
p == q        // false
p.equals(q)   // true

Logical operators

age >= 18 && hasId      // and
age < 18 || hasId       // or
!hasId                  // not

&& and || short-circuit — the right side is skipped when the result is already known. That protects you:

if (name != null && name.length() > 3) {  }   // safe
if (name != null &  name.length() > 3) {  }   // NPE: & always evaluates both
a b a && b a || b !a
true true true true false
true false false true false
false true false true true
false false false false true

Ternary

var status = points >= 50 ? "pass" : "fail";

Fine for simple cases, never nest it — use switch instead.

Dealing with null

String name = null;
name.length();   // NullPointerException

Java tells you exactly what was null:

Cannot invoke "String.length()" because "name" is null

Strategies:

if (name != null && !name.isBlank()) {  }         // check
Objects.requireNonNullElse(name, "unknown");       // fallback
Objects.requireNonNull(name, "name is required");  // fail fast
Optional<String> found = find("Ann");              // see chapter 10
Tip

Never return null for a collection — return an empty one. It saves your callers hundreds of null checks.

Keep conditions readable

var isAdult    = c.age() >= 18;
var isDomestic = c.country().equals("US");
var isActive   = !c.blocked() && c.balance() > 0;

if (isAdult && isDomestic && isActive) {  }

De Morgan: !(a && b)!a || !b, and !(a || b)!a && !b.

★ Exercises

  1. boolean isLeapYear(int year) — divisible by 4, not by 100, unless by 400.
  2. Why is "a" == "a" often true, yet unreliable? Try it in JShell.
  3. Rewrite !(age < 18 || blocked) without the leading !.
  4. boolean isValidPassword(String) — 8+ chars, a digit, an uppercase letter; null is invalid but must not throw.
  5. What does 1 == 1.0 print, and why?