3.3 Decision Making: if, if-else, and the Ternary Operator

Key Takeaways

  • Conditions in Java if statements must evaluate strictly to a primitive boolean or Boolean wrapper; numeric values such as 0 or 1 do not convert to boolean and cause compile-time errors.
  • Without enclosing curly braces {}, an if or else block governs only the single statement immediately following it, causing misleading indentation to introduce severe logical bugs.
  • The dangling else ambiguity is resolved by Java's formal grammar rule: an else binds to the closest preceding unmatched if within the same enclosing block scope.
  • The ternary operator (condition ? expr1 : expr2) is an expression that yields a value and conditionally short-circuits, evaluating only the branch selected by the condition.
  • Both branches of a ternary expression must evaluate to types compatible with the receiving variable, and mixed numeric types undergo binary numeric promotion (e.g., int and double branches promote the integer to double).
Last updated: September 2026

3.3 Decision Making: if, if-else, and the Ternary Operator

[!NOTE] Exam Focus: Oracle's "Using Decision Statements" topic area tests candidate precision on Java decision statements. Key examination traps include accidental assignment inside if conditions (if (b = true) vs if (x = 5)), unbraced single-statement execution with deceptive indentation, the dangling else scoping rule, and ternary operator branch evaluation rules and type compatibility.

In standard program execution, instructions execute sequentially from top to bottom. Decision-making statements introduce conditional branching, allowing the Java Virtual Machine to selectively execute different blocks of code based on dynamic runtime criteria.


1. Strict Boolean Condition Requirements & Common Traps

Unlike languages such as C, C++, or Python where numbers can serve as boolean conditions (e.g., 0 is falsy and non-zero is truthy), Java is strictly typed: the conditional expression governing an if statement must evaluate strictly to a primitive boolean or a Boolean wrapper object.

int count = 5;

// COMPILE ERROR: incompatible types: int cannot be converted to boolean
// if (count) {
//     System.out.println("Count is positive");
// }

// Valid Java syntax:
if (count > 0) {
    System.out.println("Count is positive");
}

The Assignment vs. Equality Trap

A classic 1Z0-811 exam question tests accidental assignment (=) instead of relational equality (==) inside an if header:

int score = 90;
// if (score = 100) { } // COMPILE ERROR: int cannot be converted to boolean

However, if the variable being tested is of type boolean, assigning a value inside the condition compiles cleanly and creates a deceptive trap:

boolean isEligible = false;

// TRAP: This is ASSIGNMENT (=), not equality (==)!
if (isEligible = true) {
    System.out.println("Granted access"); // ALWAYS EXECUTES!
}
System.out.println("isEligible is now: " + isEligible); // Prints: true

[!WARNING] Exam Watch: When inspecting if (var = value) on the exam:

  1. If var is numeric or an object reference, compilation fails (incompatible types).
  2. If var is boolean, the code compiles, mutates the variable with the assigned value, and branches based on that new boolean value!

2. The if, if-else, and if-else-if Statements

The Single if Statement

Executes its controlled statement or block if and only if the boolean condition evaluates to true:

if (temperature > 100) {
    System.out.println("High temperature alert");
}

The if-else Statement

Provides two mutually exclusive branches. Exactly one branch executes:

if (balance >= price) {
    balance -= price;
    System.out.println("Purchase successful");
} else {
    System.out.println("Insufficient funds");
}

The if-else-if Ladder

When multiple non-overlapping conditions must be tested sequentially, the if-else-if ladder evaluates conditions from top to bottom. The first condition that evaluates to true triggers its block, and all remaining branches are skipped:

int marks = 85;
char grade;

if (marks >= 90) {
    grade = 'A';
} else if (marks >= 80) {
    grade = 'B'; // Matches: assigns 'B' and skips subsequent branches
} else if (marks >= 70) {
    grade = 'C';
} else {
    grade = 'F';
}

[!TIP] Order Matters: In an if-else-if ladder, placing a broad condition before a specific condition causes the specific block to become unreachable dead code. For example, testing marks >= 60 before marks >= 90 prevents 'A' from ever being awarded.


3. Block Scoping, Indentation Traps, and the Empty Statement

In Java, curly braces {} group multiple statements into a single compound block. If curly braces are omitted, an if or else clause controls only the single statement immediately following it.

The Indentation Trap

Java compilers ignore whitespace and indentation. Indentation does not define block scope:

int score = 50;
if (score >= 60)
    System.out.println("Passed");
    System.out.println("Keep up the good work!"); // UNCONDITIONAL: Always executes!

Because braces are absent, only System.out.println("Passed"); belongs to the if. The second print statement executes unconditionally regardless of score, printing Keep up the good work!. Always use curly braces {} in production code to avoid this trap.

The Semicolon Trap (Empty Statement)

A misplaced semicolon ; immediately following an if condition creates an empty statement, rendering the condition useless:

int x = 5;
if (x > 10); // TRAP: The semicolon terminates the if statement here!
{
    System.out.println("x is greater than 10"); // ALWAYS EXECUTES!
}

4. The Dangling Else Ambiguity & JLS Resolution Rule

When if statements are nested without curly braces, an ambiguous syntactic situation known as the dangling else occurs:

int a = 5;
int b = 15;

if (a > 10)
    if (b > 10)
        System.out.println("Both are greater than 10");
else
    System.out.println("a is 10 or less"); // Which if does this else belong to?

Does the else belong to the outer if (a > 10) or the inner if (b > 10)?

Java's Formal Resolution Rule (JLS §14.5)

In Java, an unbraced else always binds to the closest preceding unmatched if statement within the same block scope.

In the code above:

  1. The else belongs to the inner if (b > 10).
  2. When a > 10 is tested, 5 > 10 evaluates to false.
  3. Because the entire inner if-else construct is contained inside the outer if statement, the inner construct is completely bypassed.
  4. Nothing is printed at all!
// What the compiler actually constructs:
if (a > 10) {
    if (b > 10) {
        System.out.println("Both are greater than 10");
    } else {
        System.out.println("a is 10 or less"); // Bound to inner if!
    }
}

To bind the else to the outer if, curly braces must explicitly enclose the inner if:

if (a > 10) {
    if (b > 10) {
        System.out.println("Both are greater than 10");
    }
} else {
    System.out.println("a is 10 or less"); // Bound to outer if
}

5. The Ternary Conditional Operator (? :)

The ternary operator is Java's only operator that takes three operands. It acts as an inline, expression-level alternative to a standard if-else block.

Syntax

booleanCondition ? expressionIfTrue : expressionIfFalse
int age = 20;
String status = (age >= 18) ? "Adult" : "Minor"; // Evaluates to "Adult"

Expression vs. Statement Distinction

The ternary construct is an expression, meaning it evaluates to a concrete value. It cannot be used as a standalone statement:

int x = 10, y = 20;

// COMPILE ERROR: not a statement
// (x > y) ? System.out.println(x) : System.out.println(y);

// CORRECT: Pass the ternary expression result as an argument
System.out.println((x > y) ? x : y);

Short-Circuit Evaluation in Ternary Operators

Just like the short-circuit logical operators (&&, ||), the ternary operator evaluates only one branch expression at runtime. If booleanCondition is true, expressionIfTrue is evaluated and expressionIfFalse is skipped; if false, only expressionIfFalse is evaluated:

int count = 5;
int result = (count > 0) ? ++count : --count;
System.out.println("count=" + count + ", result=" + result);
// Prints: count=6, result=6 (--count is NEVER evaluated!)

6. Type Compatibility & Numeric Promotion in Ternary Branches

On Exam 1Z0-811, you must verify that both ternary branch expressions are compatible with the target receiving variable.

Branch Type Rules

  1. Both branch expressions must yield types that can be converted or assigned to the target variable.
  2. When one branch is an integer and the other is a floating-point number, binary numeric promotion widens the integer branch to match the floating-point branch:
int n = 10;
double val = true ? n : 2.5;
System.out.println(val); // Prints: 10.0 (n is widened to double 10.0!)
  1. Incompatible branch types trigger a compile-time error:
// COMPILE ERROR: incompatible types: String cannot be converted to int
// int num = (5 > 2) ? 10 : "Error";

7. Nested Ternary Expressions

Ternary expressions can be chained or nested to evaluate multiple conditions. Because the ternary operator is right-associative, chained operators group from right to left:

int score = 78;
String grade = (score >= 90) ? "A"
             : (score >= 80) ? "B"
             : (score >= 70) ? "C"
             : "F";
System.out.println(grade); // Prints: C
Loading diagram...
Dangling Else Scoping and Execution Resolution Flow
Test Your Knowledge

What is the console output of the following Java program?

int x = 6;
int y = 14;
if (x > 10)
    if (y > 10)
        System.out.print("Alpha");
else
    System.out.print("Beta");
System.out.print("Gamma");

A
B
C
D
Test Your Knowledge

What is printed after executing the following Java code snippet?

boolean enabled = false;
int counter = 100;
if (enabled = true) {
    counter += 50;
} else {
    counter -= 50;
}
System.out.println("enabled=" + enabled + ", counter=" + counter);

A
B
C
D
Test Your Knowledge

What is the evaluated output of the following code involving a ternary expression with side effects?

int score = 75;
int bonus = 10;
double total = (score >= 80) ? ++bonus + score : bonus++ + (double)score / 2;
System.out.println("bonus=" + bonus + ", total=" + total);

A
B
C
D