Java If…Else

The if...else statement is how a Java program makes decisions. Instead of running every line in order from top to bottom, your code can check a condition and choose which block of statements to execute — skipping the rest. Almost every non-trivial program depends on this: validating input, branching game logic, handling different user roles, and more. Understanding exactly how Java evaluates conditions, and the subtle mistakes that trip up beginners, will save you hours of debugging later.

Overview / How It Works

An if statement evaluates a boolean expression — something that resolves to exactly true or false. If the expression is true, the block of code inside the if runs. If it’s false, that block is skipped. Unlike languages such as C or JavaScript, Java will not let you use an integer or any non-boolean value as a condition — if (1) is a compile error in Java, not a truthy value. The condition must be a genuine boolean or a boolean-returning expression (a comparison like x > 5, a boolean variable, or a call to a method that returns boolean).

Java gives you four related forms built from the same keyword:

  • if — run a block only when a condition is true.
  • if…else — run one block when true, a different block when false.
  • if…else if…else (a ladder) — test several conditions in order, running the first block whose condition is true.
  • nested if — an if statement placed inside another if or else block, for conditions that depend on each other.

Internally, the condition is evaluated once, as a single boolean value, and the JVM uses that value to decide which branch of bytecode to jump to (more on this in the “Under the Hood” section). Because only one branch ever executes, anything with side effects — like incrementing a counter or printing text — happens at most once per if evaluation, never for both branches.

Java also short-circuits logical operators used inside conditions. In a && b, if a is false, Java never evaluates b at all, because the whole expression is already guaranteed to be false. Likewise, in a || b, if a is true, b is skipped. This matters in real code: it lets you safely write if (obj != null && obj.isValid()) without risking a NullPointerException, because obj.isValid() is only reached when obj is already known to be non-null.

Syntax

if (condition) {
    // runs when condition is true
} else if (anotherCondition) {
    // runs when condition is false AND anotherCondition is true
} else {
    // runs when none of the above conditions are true
}
Part Meaning
if Keyword that starts the conditional statement.
(condition) A boolean expression in parentheses; must evaluate to true or false.
{ ... } Block of one or more statements executed when the condition holds. Braces are optional for a single statement but strongly recommended (see Common Mistakes).
else if Optional; adds another condition, checked only if all prior conditions were false. You can chain as many as you need.
else Optional; a catch-all block that runs only if every prior condition was false.

Only one block in the entire chain ever runs. Java evaluates conditions top to bottom and stops at the first one that is true.

Examples

Example 1: A simple if statement

public class Main {
    public static void main(String[] args) {
        int number = 12;

        if (number > 0) {
            System.out.println(number + " is positive.");
        }

        System.out.println("Done checking.");
    }
}

Output:

12 is positive.
Done checking.

Here, number > 0 evaluates to true, so the message inside the braces prints. The final println is outside the if block, so it always runs regardless of the condition — a useful distinction to notice as you read code.

Example 2: if…else for a binary choice

public class Main {
    public static void main(String[] args) {
        int number = 7;

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

Output:

7 is odd.

The condition number % 2 == 0 uses the modulo operator to test for a remainder. Since 7 % 2 is 1, the condition is false, so control jumps straight to the else block. Exactly one of the two branches runs — never both, never neither.

Example 3: if…else if ladder with a nested if

public class Main {
    public static void main(String[] args) {
        int score = 82;
        boolean lateSubmission = true;
        char grade;

        if (score >= 90) {
            grade = 'A';
        } else if (score >= 80) {
            grade = 'B';
        } else if (score >= 70) {
            grade = 'C';
        } else if (score >= 60) {
            grade = 'D';
        } else {
            grade = 'F';
        }

        if (lateSubmission) {
            if (grade != 'F') {
                grade = (char) (grade + 1);
            }
        }

        System.out.println("Score: " + score);
        System.out.println("Final grade: " + grade);
    }
}

Output:

Score: 82
Final grade: C

The ladder checks each range in order: since score >= 90 is false but score >= 80 is true, grade becomes 'B', and the remaining else if/else branches are skipped entirely. Then a nested if inside the lateSubmission check lowers the grade by one letter (using the fact that char values are just numbers under the hood, so 'B' + 1 becomes 'C') — but only if the student didn’t already fail. This shows how nested conditions let you apply extra logic that depends on a decision already made.

Under the Hood

When javac compiles an if statement, it doesn’t generate anything resembling English “if/else” — it produces conditional jump bytecode instructions. For a comparison like if (score >= 80), the compiler emits something conceptually equivalent to: compute score, compute 80, compare them with an instruction such as if_icmplt (“if int compare is less-than, jump”), and jump past the if block to the next branch when the comparison fails. After the if block, an unconditional goto instruction skips over the else/else if blocks so they don’t accidentally execute too.

This is why exactly one branch runs: the JVM’s program counter physically jumps to only one location in the compiled method. There’s no “forgetting” to skip a branch — the jump targets are baked into the bytecode at compile time. It’s also why the condition must be a genuine boolean: the comparison instructions the JVM uses (like ifeq, ifne, if_icmpge) operate on well-defined true/false semantics, and Java’s type checker enforces that guarantee at compile time rather than at runtime, unlike C’s “any nonzero value is truthy” behavior.

Short-circuit evaluation of && and || is implemented the same way — as conditional jumps that skip evaluating the right-hand operand entirely, rather than as a boolean AND/OR CPU instruction applied to two already-computed values. That’s a real performance and safety feature, not just convenient syntax.

Common Mistakes

Mistake 1: Using = instead of == inside a boolean condition

Wrong:

boolean isEligible = false;
if (isEligible = true) {
    System.out.println("Eligible!");
}

Output:

Eligible!

This compiles because isEligible = true is itself an assignment expression that evaluates to the assigned value (true) — Java only blocks this trap when the variable isn’t already boolean. The condition is always true, and worse, isEligible is silently overwritten. Use == to compare, or simply use the boolean variable directly:

Corrected:

boolean isEligible = false;
if (isEligible) {
    System.out.println("Eligible!");
} else {
    System.out.println("Not eligible.");
}

Output:

Not eligible.

Mistake 2: Omitting braces on multi-statement blocks

Wrong:

int score = 45;
if (score >= 60)
    System.out.println("Passed");
    System.out.println("Great job!");

Output:

Great job!

Without braces, only the single statement immediately after if is part of the conditional block — indentation is purely cosmetic to Java, not structural. Here "Great job!" is treated as a separate, unconditional statement, so it prints even though the student failed. Always use braces so the intended grouping matches the actual grouping:

Corrected:

int score = 75;
if (score >= 60) {
    System.out.println("Passed");
    System.out.println("Great job!");
}

Output:

Passed
Great job!

Best Practices

  • Always use braces { }, even for single-statement blocks — it prevents the “dangling statement” bug and makes future edits safer.
  • Order else if branches from most specific to least specific (or most likely to least likely) so the correct branch is found quickly and clearly.
  • Compare objects, including String, with .equals() rather than ==, which compares references, not content.
  • Keep conditions readable: extract a complex boolean expression into a well-named boolean variable or method, e.g. boolean isEligible = age >= 18 && hasValidId;.
  • Avoid deeply nested if statements when possible; consider “early return” or combining conditions with &&/|| to flatten logic.
  • When you have many discrete values to branch on (not ranges), consider a switch statement instead of a long else if ladder.
  • Rely on short-circuit evaluation intentionally — put null checks or cheap conditions first in an && chain to guard against errors in later checks.

Practice Exercises

  • Exercise 1: Write a program that declares an integer temperature and prints "Hot" if it is 30 or above, "Warm" if it is between 15 and 29 inclusive, and "Cold" otherwise, using an if...else if...else ladder.
  • Exercise 2: Write a program that takes two integers and prints the larger one, or "Equal" if they are the same, without using Math.max.
  • Exercise 3: Write a program with a boolean hasTicket and an integer age. Print "Entry allowed" only if hasTicket is true AND age is at least 12; otherwise print "Entry denied". Use a nested if to also print "Discount applied" when entry is allowed and age is under 18.

Summary

  • if runs a block only when its boolean condition is true; Java requires a genuine boolean, not a numeric “truthy” value.
  • if...else picks between exactly two branches; if...else if...else chains multiple conditions and stops at the first true one.
  • Nested if statements let you apply conditions that depend on an outer decision already made.
  • The JVM compiles conditions into conditional jump bytecode, guaranteeing exactly one branch executes.
  • && and || short-circuit, skipping the right-hand operand when the result is already determined.
  • Always use braces, compare objects with .equals(), and keep conditions readable to avoid classic bugs.