☕ Java

if-else Statement

The if-else statement extends the basic if by providing an alternative block that executes when the condition is false. It guarantees that exactly one of two blocks always executes — either the if block (condition true) or the else block (condition false). The if-else-if chain extends this to choose among more than two alternatives.

if-else Syntax and Basic Usage

The else block is attached directly to the if block. Exactly one of the two blocks executes — never both, never neither. The else block has no condition of its own; it is the catch-all that executes when the if condition is false.
Java
// ── Basic syntax: ────────────────────────────────────────────────────
//
//  if (condition) {
//      // executes when condition is TRUE
//  } else {
//      // executes when condition is FALSE
//  }
//  // always continues here

// ── Simple example: ───────────────────────────────────────────────────
int age = 16;

if (age >= 18) {
    System.out.println("Adult — can vote.");
} else {
    System.out.println("Minor — cannot vote yet.");  // executes
}

// ── Exactly one block always executes: ───────────────────────────────
int number = 7;

if (number % 2 == 0) {
    System.out.println(number + " is even.");
} else {
    System.out.println(number + " is odd.");    // executes — 7 % 2 = 1
}

// ── Practical: login validation: ─────────────────────────────────────
String enteredPassword = "secret123";
String correctPassword = "secret123";

if (enteredPassword.equals(correctPassword)) {
    System.out.println("Access granted.");       // executes
    openDashboard();
} else {
    System.out.println("Access denied.");
    logFailedAttempt();
}

// ── Returning from both branches: ────────────────────────────────────
public String getTicketPrice(boolean isStudent) {
    if (isStudent) {
        return 5.00";
    } else {
        return 10.00";
    }
}

// ── Idiomatic version — else not needed after return: ─────────────────
public String getTicketPriceClean(boolean isStudent) {
    if (isStudent) {
        return 5.00";
    }
    return 10.00";    // implicit else — reached only when !isStudent
}

if-else-if Chain

The if-else-if chain evaluates conditions in order from top to bottom. As soon as one condition is true its block executes and the rest of the chain is skipped entirely. Only one block executes regardless of how many conditions are true. The optional final else acts as a default case when no condition matches.
Java
// ── Syntax: ──────────────────────────────────────────────────────────
//
//  if (condition1) {
//      // executes when condition1 is true
//  } else if (condition2) {
//      // executes when condition1 false AND condition2 true
//  } else if (condition3) {
//      // executes when condition1,2 false AND condition3 true
//  } else {
//      // executes when ALL conditions are false (default)
//  }

// ── Grade classification: ─────────────────────────────────────────────
int score = 73;

if (score >= 90) {
    System.out.println("Grade: A");
} else if (score >= 80) {
    System.out.println("Grade: B");
} else if (score >= 70) {
    System.out.println("Grade: C");     // executes — 73 >= 70
} else if (score >= 60) {
    System.out.println("Grade: D");
} else {
    System.out.println("Grade: F");
}

// ── IMPORTANT: Only the first matching branch executes: ───────────────
// Even though score=73 satisfies BOTH (score >= 70) AND (score >= 60),
// only the FIRST matching branch (score >= 70) executes.
// The chain stops at the first true condition.

// ── Order matters — wrong order produces wrong results: ───────────────
// BAD — all scores >= 60 would match the first condition:
int s = 95;
if (s >= 60) {
    System.out.println("Grade: D");   // WRONG — catches 95 too!
} else if (s >= 70) {
    System.out.println("Grade: C");   // never reached for high scores
} else if (s >= 90) {
    System.out.println("Grade: A");   // never reached
}

// GOOD — most restrictive condition first:
if (s >= 90) {
    System.out.println("Grade: A");   // executes for s=95
} else if (s >= 80) {
    System.out.println("Grade: B");
} else if (s >= 70) {
    System.out.println("Grade: C");
} else {
    System.out.println("Grade: D or below");
}

// ── Without a final else — nothing executes if no match: ─────────────
int statusCode = 418;

if (statusCode == 200) {
    System.out.println("OK");
} else if (statusCode == 404) {
    System.out.println("Not Found");
} else if (statusCode == 500) {
    System.out.println("Server Error");
}
// statusCode=418 — no branch executes, no output
// Add a final else to handle unexpected values:
// } else {
//     System.out.println("Unknown status: " + statusCode);
// }

Ternary Operator

The ternary operator (?:) is a compact inline alternative to a simple if-else that assigns one of two values. It is an expression (produces a value) rather than a statement, making it usable inside variable assignments, method arguments, and string concatenation. Use it only for simple two-choice value selections — complex logic belongs in a full if-else.
Java
// ── Syntax: condition ? valueIfTrue : valueIfFalse ───────────────────

// ── if-else vs ternary — equivalent: ─────────────────────────────────
int age = 20;

// if-else version:
String label;
if (age >= 18) {
    label = "Adult";
} else {
    label = "Minor";
}

// Ternary version — same result, one line:
String label2 = age >= 18 ? "Adult" : "Minor";

System.out.println(label2);    // Adult

// ── Inline in expressions: ────────────────────────────────────────────
int score = 55;
System.out.println("Result: " + (score >= 60 ? "Pass" : "Fail"));

// ── In method arguments: ─────────────────────────────────────────────
boolean isPremium = true;
applyDiscount(isPremium ? 0.20 : 0.05);

// ── Nested ternary — possible but avoid for readability: ──────────────
int s = 75;
String grade = s >= 90 ? "A"
             : s >= 80 ? "B"
             : s >= 70 ? "C"
             : s >= 60 ? "D"
             : "F";
// Works, but an if-else-if chain is clearer for 3+ conditions.

// ── Ternary with null checks: ─────────────────────────────────────────
String name = null;
String display = name != null ? name : "Guest";
// Same as: String display = Objects.requireNonNullElse(name, "Guest");

// ── When NOT to use ternary: ──────────────────────────────────────────
// BAD — ternary used for side effects / actions (not value selection):
// isPremium ? sendWelcomeEmail() : sendTrialEmail();  // confusing

// GOOD — use if-else for actions:
if (isPremium) {
    sendWelcomeEmail();
} else {
    sendTrialEmail();
}

Practical if-else Patterns

These patterns appear repeatedly in professional Java code. The guard clause (early return) pattern flattens deeply nested if-else chains into a flat sequence of checks. The strategy of returning early from methods avoids the need for else when the if block always exits.
Java
// ── Pattern 1: Guard clauses — validate inputs early, return fast: ────
// BAD — deeply nested, hard to read:
public String processOrder(Order order) {
    if (order != null) {
        if (!order.getItems().isEmpty()) {
            if (order.getCustomer() != null) {
                // actual logic buried 3 levels deep
                return "Processed";
            } else {
                return "No customer";
            }
        } else {
            return "No items";
        }
    } else {
        return "No order";
    }
}

// GOOD — guard clauses: check error cases first, return early:
public String processOrder(Order order) {
    if (order == null)                  { return "No order"; }
    if (order.getItems().isEmpty())     { return "No items"; }
    if (order.getCustomer() == null)    { return "No customer"; }

    // Happy path — uncluttered, easy to read:
    return "Processed";
}

// ── Pattern 2: Default value with else: ───────────────────────────────
public int getPageSize(Integer requestedSize) {
    if (requestedSize != null && requestedSize > 0
                              && requestedSize <= 100) {
        return requestedSize;
    } else {
        return 20;      // default page size
    }
}

// ── Pattern 3: Accumulate result based on conditions: ─────────────────
public String buildUserSummary(User user) {
    StringBuilder sb = new StringBuilder();
    sb.append("User: ").append(user.getName());

    if (user.isPremium()) {
        sb.append(" [PREMIUM]");
    } else {
        sb.append(" [FREE]");
    }

    if (user.isVerified()) {
        sb.append(" ✓");
    }

    if (user.getAge() >= 18) {
        sb.append(" (Adult)");
    } else {
        sb.append(" (Minor)");
    }

    return sb.toString();
}

// ── Pattern 4: Command dispatch: ─────────────────────────────────────
public void handleCommand(String command) {
    if (command.equals("START")) {
        startEngine();
    } else if (command.equals("STOP")) {
        stopEngine();
    } else if (command.equals("STATUS")) {
        printStatus();
    } else {
        System.out.println("Unknown command: " + command);
        // For many commands, consider switch or a Map<String, Runnable>
    }
}

Related Topics in Control Statements

while Loop
The while loop is a condition-controlled loop — it continues executing as long as its boolean condition remains true, without specifying in advance how many iterations will occur. It is the natural choice for reading input until end-of-stream, polling until a condition changes, retrying an operation, or any scenario where the termination condition depends on data or events that cannot be predetermined. This entry covers syntax, execution flow, common patterns, infinite loops with controlled exit, and the differences between while and for.
do-while Loop
The do-while loop is Java's only post-test loop — the condition is evaluated after the body executes, which guarantees the body runs at least once regardless of the condition's initial value. This property makes do-while the natural fit for scenarios where the first execution must happen before the first check: menu-driven programs, input validation, digest computation, and game turns. This entry covers syntax, when to use do-while over while, input validation patterns, and the subtle differences that matter in practice.
Enhanced for Loop
The enhanced for loop — also called the for-each loop — was introduced in Java 5 to provide a clean, readable syntax for iterating over arrays and any class that implements Iterable. It eliminates index management and iterator boilerplate entirely. The developer declares what each element is and what to do with it, without concerning themselves with how the iteration mechanism works. This entry covers syntax, the Iterable contract, limitations compared to the indexed loop, modification restrictions, and how for-each maps to iterators under the hood.
break Statement
The break statement immediately terminates the nearest enclosing loop or switch block and transfers control to the first statement after that block. It is one of Java's three jump statements alongside continue and return. break is essential for exiting loops early when a search condition is met, preventing infinite loops from running forever, and stopping switch execution after a matched case.