skip to content

When should you prefer a ternary over an if/else, and what are the readability and correctness pitfalls a senior engineer should police in code review?

level: middleimportance: should knowfreq 45%

answer

  1. Ternary = choose one value; if/else = do work / flow
  2. No (or shallow) nesting — extract a method instead
  3. Watch silent widening (flag ? 0 : 1.5 == 0.0)
  4. Watch unbox-null NPE (primitive + nullable wrapper)
  5. Parenthesize inside larger expressions (low precedence)

basics

~20 s

Use a ternary for short, simple value selection (assign or return one of two values). Avoid it for side effects or when nesting many conditions — that gets hard to read. For anything complex, an if/else is clearer.

solid answer

~50 s

Prefer a ternary when you are choosing **a single value** based on a condition and an `if/else` would just be noise — assignments, returns, or inline arguments read better as `x = cond ? a : b`. Avoid it when the branches **do things** (side effects, multiple statements), because a ternary is an expression and only its value is used; an `if/else` makes intent clear. The main readability pitfall is **nesting**: chained ternaries can mimic an if-ladder but quickly become unreadable, so cap nesting (often a single level by convention) or extract a method. Correctness pitfalls to police in review: silent **numeric widening** (`flag ? 0 : 1.5` is `double`), and **auto-unboxing NPEs** when one branch is a primitive and the other a nullable wrapper (e.g. `cond ? 0 : map.get(k)`). Also watch operator precedence — the ternary binds loosely, so wrap it in parentheses inside larger expressions (e.g. string concatenation).

code

java · 13 lines
java
// GOOD: simple value selection
String label = count == 1 ? "item" : "items";

// PITFALL: precedence — '+' binds before '?:'
// System.out.println("n=" + n > 0 ? "pos" : "neg"); // wrong / won't compile
System.out.println("n=" + (n > 0 ? "pos" : "neg"));   // correct

// PITFALL: silent widening -> double
Object o = flag ? 0 : 1.5;   // 0 becomes 0.0; result type is double

// PREFER if/else when there are side effects:
if (flag) { audit.log("on"); enable(); }
else      { audit.log("off"); disable(); }

go deeper

for a junior

Knows a ternary is good for short value selection and that an if/else is needed for multiple actions.

for a middle

Can argue the expression-vs-statement distinction, caps nesting, and remembers the precedence/parentheses pitfall.

for a senior

Reviews for the correctness traps (widening, unbox-null NPE, precedence) and sets a team convention on nesting; balances brevity against clarity.

for a principal

Defines org-wide style and lint rules (e.g. ban nested ternaries), ties the boxing/widening hazards to defect data, and coaches reviewers on what to police.

## Why this is a judgment call, not a rule The ternary and `if/else` overlap but are not interchangeable: a ternary is an **expression** (produces a value), while `if/else` is a **statement** (controls flow). Choosing well is about matching the tool to intent and protecting readers from subtle traps. ## When the ternary is the right tool Use it when you are selecting **one value**: ```java int max = a > b ? a : b; return user == null ? "guest" : user.name(); String label = count == 1 ? "item" : "items"; ``` In each case an `if/else` would force a temporary variable or a duplicated `return`, adding noise without clarity. Ternaries also shine **inline** where a statement cannot go: method arguments, string templates, field initializers. ## When to avoid it 1. **Side effects / multiple statements.** Since only the *value* is used, putting work (logging, mutation, multiple actions) in a ternary obscures it. Use `if/else`. 2. **Deep nesting.** A chain like `a ? b : c ? d : e ? f : g` technically reads as an if-ladder (right-associative) but is hard to scan and easy to misread. Convention in many style guides: **no nested ternaries**, or at most one level; otherwise use `if/else` or extract a helper method, or a `switch`/`Map` for many cases. 3. **Branches with different, awkward types** that trigger promotion/boxing surprises (below). ## Correctness pitfalls to police in review - **Silent numeric widening.** Because the result has one type computed from both branches, `flag ? 0 : 1.5` is a `double` and even the `0` path yields `0.0`. Reviewers should flag mismatched numeric literals where an `int` was intended. - **Auto-unboxing NPE.** Mixing a primitive and a nullable wrapper unboxes the wrapper; if it is `null`, you get a `NullPointerException` with no visible dereference — e.g. `boolean b = cond ? flags.get(k) : false;`. This is a top production-bug source. - **Precedence / parentheses.** The conditional operator has very low precedence. In `"x=" + cond ? "a" : "b"` the `+` binds first, producing `"x=" + cond` then `? ...`, usually a compile error or wrong result. Always parenthesize a ternary embedded in a larger expression: `"x=" + (cond ? "a" : "b")`. - **Assignment vs comparison in the condition** and other generic boolean mistakes apply as anywhere. ## Formatting that helps When a ternary is unavoidably multi-line, align the `?` and `:` so the structure is visible: ```java String grade = score >= 90 ? "A" : score >= 80 ? "B" : "F"; ``` Even so, prefer extracting such ladders into a method with early returns once they exceed two or three cases. ## The review heuristic Ask: *Does this select one value and read at a glance?* If yes, ternary. *Does it do work, or need more than a quick glance?* If yes, `if/else`. Then scan for the three correctness traps: widening, unboxing-null, and missing parentheses.

  • Why is System.out.println("n=" + n > 0 ? "pos" : "neg") wrong?
    The conditional operator has lower precedence than +, so it parses as ("n=" + n) > 0 ? ..., which compares a String with > and fails to compile. Wrap the ternary in parentheses: "n=" + (n > 0 ? "pos" : "neg").
  • Give one case where if/else is clearly better than a ternary.
    When each branch performs actions (logging, mutating state, multiple statements). A ternary only uses its value, so side-effect work belongs in if/else where the intent and control flow are explicit.

A ternary is a pocket knife: perfect for a quick, small cut (pick one value). For carpentry — multiple steps, heavy work — you reach for the full toolbox (if/else). Using the pocket knife to build furniture is where things get messy and dangerous.

saying these in an interview costs you the question

  • Using nested ternaries where an if-ladder or switch would be clearer
  • Putting side effects in ternary branches
  • Forgetting parentheses around a ternary inside string concatenation
  • Ignoring widening/unboxing traps as 'just style' — they are correctness issues

context