Java If Else

Su Suriya Ravichandran Updated 14 Nov 2026
7 min read ·Lesson 17 of 133

The if statement runs a block of code only when a condition is true. Adding else provides an alternative path, and chaining else if handles several mutually exclusive cases. Together they are the most direct way to make a program choose what to do.

The if Statement

if (condition) {
    // runs only when condition is true
}
int temperature = 38;

if (temperature > 35) {
    System.out.println("Heat warning: stay hydrated.");
}
System.out.println("Forecast complete.");

Output:

Heat warning: stay hydrated.
Forecast complete.

The condition in parentheses is evaluated once. If it is true, the block runs; if false, the block is skipped entirely and execution continues after the closing brace. The last line runs in both cases because it is outside the block.

The parentheses are mandatory, and the condition must be a boolean expression. if (temperature) does not compile.

The else Clause

else supplies a block that runs when the condition is false. Exactly one of the two blocks runs.

int marks = 42;

if (marks >= 50) {
    System.out.println("Pass");
} else {
    System.out.println("Fail");
}

Output:

Fail

else has no condition of its own. It is the "otherwise" case for the if immediately before it.

else if Chains

When there are more than two outcomes, chain conditions with else if:

int score = 76;
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';
}

System.out.println("Grade: " + grade);   // Grade: C

How the chain is evaluated

Conditions are tested top to bottom, and the first one that is true wins. Its block runs and every remaining branch is skipped, even if later conditions would also be true.

For score = 76:

  1. 76 >= 90: false, move on.
  2. 76 >= 80: false, move on.
  3. 76 >= 70: true. Assign 'C' and leave the chain.

The fourth condition, 76 >= 60, is never evaluated, though it is also true. This is why the chain can use only lower bounds: reaching the >= 70 test already implies the score is below 80.

Order matters

Reordering the same conditions breaks the logic:

if (score >= 60) {
    grade = 'D';            // every passing score lands here
} else if (score >= 70) {
    grade = 'C';            // unreachable for any score
} ...

With range checks, order from the most restrictive to the least restrictive (here, highest threshold first).

The final else

The trailing else catches everything not matched above. Without it, a chain might run no branch at all. In the grade example, the final else also guarantees that grade is assigned on every path; remove it and the compiler reports that grade might not have been initialized when it is printed.

Separate ifs Versus else if

Several independent if statements are not the same as an else if chain:

int n = 15;

// Independent checks: every true condition runs
if (n % 3 == 0) System.out.println("divisible by 3");
if (n % 5 == 0) System.out.println("divisible by 5");

// Chain: only the first true condition runs
if (n % 3 == 0) {
    System.out.println("divisible by 3");
} else if (n % 5 == 0) {
    System.out.println("divisible by 5");
}

The first form prints both lines; the second prints only divisible by 3. Use separate ifs when the conditions are independent and several may apply. Use a chain when the cases are mutually exclusive and exactly one should apply.

Braces and Single Statements

When a branch contains one statement, braces are optional:

if (balance < 0)
    System.out.println("Overdrawn");
else
    System.out.println("OK");

Omitting them invites a specific bug when code is added later:

if (balance < 0)
    System.out.println("Overdrawn");
    sendAlert();            // NOT part of the if: runs every time

Indentation means nothing to the compiler; only the first statement belongs to the if. Always using braces makes the structure explicit and prevents this.

A stray semicolon causes the same kind of problem:

if (balance < 0); {
    System.out.println("Overdrawn");   // always runs
}

The ; is an empty statement that serves as the entire body of the if. The block below is an independent statement.

Nested if Statements

An if can appear inside another if or else block:

boolean loggedIn = true;
boolean isAdmin = false;

if (loggedIn) {
    if (isAdmin) {
        System.out.println("Admin dashboard");
    } else {
        System.out.println("User dashboard");
    }
} else {
    System.out.println("Please log in");
}

The dangling else

Without braces, an else always belongs to the nearest preceding unmatched if:

if (loggedIn)
    if (isAdmin)
        System.out.println("Admin");
else
    System.out.println("Please log in");   // actually pairs with if (isAdmin)

Despite the indentation, a logged-in non-admin sees "Please log in", and a logged-out user sees nothing. Braces remove the ambiguity.

Flattening with early returns

Deep nesting is hard to follow. Inside a method, checking failure cases first and returning early keeps the main logic at one level:

// Nested
void withdraw(Account acc, double amount) {
    if (acc != null) {
        if (!acc.isFrozen()) {
            if (amount <= acc.getBalance()) {
                acc.debit(amount);
            } else {
                System.out.println("Insufficient funds");
            }
        } else {
            System.out.println("Account frozen");
        }
    }
}

// Guard clauses
void withdraw(Account acc, double amount) {
    if (acc == null) return;
    if (acc.isFrozen()) {
        System.out.println("Account frozen");
        return;
    }
    if (amount > acc.getBalance()) {
        System.out.println("Insufficient funds");
        return;
    }
    acc.debit(amount);
}

Both behave identically. In the second, each rejection is handled next to the check that triggers it, and the successful path is the last unindented line.

Combining Conditions Instead of Nesting

Two nested ifs with no else on the outer one can be merged with &&:

if (age >= 18) {
    if (hasId) {
        allowEntry();
    }
}

// equivalent
if (age >= 18 && hasId) {
    allowEntry();
}

Keep the nesting only when the outer branch has its own else or does additional work.

if Versus the Ternary Operator

When an if/else exists only to assign one of two values to a variable, the ternary operator expresses it in one line:

String status;
if (stock > 0) {
    status = "In stock";
} else {
    status = "Sold out";
}

String status = stock > 0 ? "In stock" : "Sold out";

Use if when the branches execute statements (printing, calling methods, updating several variables) or when there are more than two outcomes.

Variables Declared Inside Branches

A variable declared in a branch exists only inside that block:

if (isMember) {
    double discount = 0.1;
}
System.out.println(discount);   // compile error: discount not in scope

To use a value after the if, declare the variable before it and assign it in each branch:

double discount;
if (isMember) {
    discount = 0.1;
} else {
    discount = 0.0;
}
System.out.println(discount);

The compiler checks that every path assigns discount; omitting the else would be a compile error.

Practical Example: Electricity Bill with Slab Rates

Utility bills are often charged in slabs: each band of units has its own rate.

public class ElectricityBill {
    static double calculate(int units) {
        if (units < 0) {
            throw new IllegalArgumentException("Units cannot be negative");
        }

        double amount;
        if (units <= 100) {
            amount = 0;                                    // first 100 units free
        } else if (units <= 200) {
            amount = (units - 100) * 2.25;
        } else if (units <= 500) {
            amount = 100 * 2.25 + (units - 200) * 4.50;
        } else {
            amount = 100 * 2.25 + 300 * 4.50 + (units - 500) * 6.60;
        }

        if (amount > 0) {
            amount += 50;                                  // fixed charge, only when billed
        }
        return amount;
    }

    public static void main(String[] args) {
        int[] readings = {80, 150, 350, 620};
        for (int u : readings) {
            System.out.printf("%4d units -> %8.2f%n", u, calculate(u));
        }
    }
}

Output:

  80 units ->     0.00
 150 units ->   162.50
 350 units ->   950.00
 620 units ->  2417.00

The first if rejects invalid input before any calculation. The chain then picks exactly one slab, from lowest to highest; because earlier branches have already handled smaller values, each test needs only an upper bound. Each branch adds the full cost of the lower slabs plus the partial cost of the current one. For 350 units: 100 × 2.25 = 225, plus 150 × 4.50 = 675, giving 900, plus the fixed charge of 50. A second, independent if applies the fixed charge, since it is a separate rule rather than another case of the slab choice.

0 Comments

Reviewed before they appear

No comments yet.

Java
Java Introduction Java Features Java Syntax Java Comments Java Statements Java Output Java Variables Java Data Types Java Type Casting Java Operators Java Strings Java Numbers Java Math Java Booleans Java User Input Java Conditions Java If Else Java Switch Java While Loop Java For Loop Java Break Java Continue Java Arrays Java Methods Java Parameters Java Return Values Java Scope Java Recursion Install Java Install JDK Java IDEs Java JDK Java JRE Java JVM Java Compiler Java File Compile Java Run Java JShell Basics Java Packages Java OOP Java Classes Java Objects Class Methods Constructors Constructor Overload this Keyword static Keyword final Keyword Encapsulation Inheritance Polymorphism Abstraction Access Modifiers super Keyword Method Overload Method Override Instanceof Operator Nested Classes Inner Classes Anonymous Classes Enums Records Array Basics Array Length Loop Arrays Multidimensional Arrays Array Copy Array Sorting Array Search ArrayList LinkedList HashSet TreeSet HashMap TreeMap Queue Interface Deque Interface Stack Class Iterator List Interface Set Interface Map Interface Collections Class Comparable Comparator Generics Basics Generic Classes Generic Methods Wildcards String Basics String Length String Methods String Concatenation String Compare String Search String Replace String Split String Format StringBuilder StringBuffer Text Blocks Regular Expressions Number Types Integer Class Float Class Double Class BigInteger BigDecimal Math Class Random Numbers Number Format Date Basics LocalDate LocalTime LocalDateTime ZonedDateTime Date Formatting Date Parsing Period Class Duration Class Java Instant Class Java Exception Basics Java try...catch Java Multiple Catch Blocks Java finally Block Java throw Keyword Java throws Keyword Java Checked Exceptions Java Unchecked Exceptions Java Custom Exceptions Java try-with-resources Java Exception Chaining
Ask about this post
AI Ask about this post

Ask questions about Java If Else and get answers drawn from it.

Signed-in readers only.