if, else-if and else

Until now, every program ran every line, top to bottom. Real programs make decisions: approve or decline, pass or fail, free delivery or not. In Java, the basic decision-maker is if. You'll learn every form of it, the mistakes that cause real outages, and the jump instructions the JVM uses to skip code.

Module 3 · Control Flow⏱ 16 minBeginnerNo install needed
1 The story

The result-day grading program

Results are out. Arjun Sir asks Riya to write a small program that converts marks into a grade: 90 and above is A+, 75 and above is A, 60 and above is B, 40 and above is C, and below 40 is Fail. Her first version gives a student with 95 marks the grade C.

marks = 72 ≥ 90? no ≥ 75? no ≥ 60? yes Grade B ≥ 40? else never checked myphatshala.in
Riya

Sir, my first check was if (marks >= 40), then else if (marks >= 60) and so on. A student with 95 got a C!

Arjun Sir

An else-if ladder stops at the first true condition. 95 is ≥ 40, so the very first check matched, and Java never looked further. Order the checks from the strictest to the loosest.

Riya

So for 72, Java checks 90, then 75, then 60, finds a match, and skips everything else?

Arjun Sir

Exactly. Behind the screen, the JVM literally jumps over the code it skips. Let's see those jumps.

2 Definition

What is an if statement?

Formal definition (write this in exams)

The if statement is a conditional control-flow statement that executes a statement or block only when a boolean expression evaluates to true. An optional else clause runs when the condition is false. Several conditions can be chained with else if, forming an if-else-if ladder in which only the first matching branch executes.

In simple words

if asks a yes/no question. Yes → run this block. No → skip it (or run the else block). With a ladder, Java asks the questions in order and stops at the first “yes”.

Words you'll meet in this lesson

ConditionThe boolean expression in brackets: marks >= 40.
BranchOne of the possible paths the program can take.
BlockThe statements inside { } that belong to a branch.
Nested ifAn if inside another if's block.
Guard clauseAn early if that handles a bad case and returns immediately.
Dangling elseAn else that belongs to a different if than it seems; always pairs with the nearest if.

The four forms

FormSyntaxUse when
ifif (cond) { … }Something should happen only sometimes
if-elseif (cond) { … } else { … }Exactly one of two things must happen
else-if ladderif (a) { … } else if (b) { … } else { … }Choosing one of several ranges or cases
nested ifif (a) { if (b) { … } }A second check only makes sense after the first passes

Exam tip: the condition must be a boolean. Unlike C, if (1) or if (x = 5) won't compile. Braces are optional for a single statement, but without them only the first statement belongs to the if, which is a classic trap question.

3 Types and ways to use it

Each form, with its typical use

Simple if

if (balance < 100) { warnLowBalance(); }
Do something extra only in some cases.

Optional action

if-else

if (pinCorrect) { approve(); } else { decline(); }
Two outcomes; exactly one happens.

Either / or

else-if ladder

Grades, tax slabs, delivery charges by distance. Order matters: the first true condition wins.

Ranges

Nested if

if (age >= 18) { if (hasId) { … } }
Often clearer as age >= 18 && hasId or a guard clause.

Use sparingly

Writing clean conditions

Instead ofWriteWhy
if (isPaid == true)if (isPaid)It's already a boolean
if (x) { return true; } else { return false; }return x;Shorter, same meaning
Deep nesting of ifsGuard clauses: if (!valid) return;Keeps the main path flat and readable
if (a) x = 1; else x = 2;x = a ? 1 : 2;Ternary for simple value choices
4 Step by step

Building the grading ladder

  1. Write the strictest condition first

    if (marks >= 90) {
        grade = "A+";
    }
    javac compiles the opposite test: “if marks < 90, jump past this block”. The bytecode is if_icmplt (if int compare less-than).
  2. Add else-if branches, from strict to loose

    } else if (marks >= 75) {
        grade = "A";
    } else if (marks >= 60) {
        grade = "B";
    }
    At the end of each block, javac adds a goto that jumps to the code after the whole ladder. That's how the other branches get skipped.
  3. Finish with else

    } else {
        grade = "Fail";
    }
    The final else guarantees grade is always assigned. Without it, javac would complain “variable grade might not have been initialized” when you print it.
  4. Always use braces

    if (balance < 100)
        System.out.println("Low balance");
        System.out.println("Please recharge");   // NOT part of the if!
    Indentation means nothing to javac. Without braces, only the first statement is inside the if; the second runs every time.
  5. Test the boundaries

    Try 90, 89, 75, 74, 60, 59, 40, 39, 0 and 100: the values right at each edge.

    Most if-else bugs are off-by-one mistakes at boundaries: > where >= was meant. Testing the exact edge values catches them.
5 See it happen

marks = 72 through the ladder: both views

Left: the code, with the line being checked. Right: the bytecode and the jumps the JVM takes.

One value, five possible branches 6 steps
What you see int marks = 72; if (marks >= 90) { grade = "A+"; } else if (marks >= 75) { grade = "A"; } else if (marks >= 60) { grade = "B"; } else if (marks >= 40) { … } else { grade = "Fail"; } System.out.println(…grade); marks is 72. 72 ≥ 90? false → skip this block 72 ≥ 75? false → skip this block 72 ≥ 60? true → enter this block grade = "B". The rest is skipped. Output: Marks 72: Grade B myphatshala.in
Behind the screen 0:bipush 72 · istore_1 3:iload_1 · bipush 90 6:if_icmplt 15← if marks < 90, jump 9:ldc "A+" · astore_2 · goto 54 15:iload_1 · bipush 75 18:if_icmplt 27 21:ldc "A" · astore_2 · goto 54 27:iload_1 · bipush 60 30:if_icmplt 39 33:ldc "B" · astore_2 · goto 54 39…54:C / Fail branches · println jump →15 jump →27 72 < 60? no → fall through javac turned the ladder into compares and jumps. The test is inverted: “less than 90? then jump away”. Another jump skips the A block. No jump this time: execution falls into the B block. goto 54 leaps over every remaining branch. Offset 54 onwards prints the result. myphatshala.in
6 Real-world use

Decisions in real systems

Almost every business rule is an if-else somewhere. Here's where they show up.

Watch it with an example: delivery charge slabs

A food app charges delivery by order value. Follow two orders down the if / else-if ladder: Java checks conditions from the top and stops at the first true one.

Two orders through an else-if ladder 6 steps
Animated example if (amount < 199) fee = 49 else if (amount < 499) fee = 29 else fee = 0 (free) order Rs 349 Rs 650 349 < 199? false → next check 349 < 499? true → fee 29, rest skipped Pay 349 + 29 = 378 650: false, false → else 650 → free delivery. Pay 650 myphatshala.in
Approved

1. Payment approval

A payment passes a chain of checks: valid PIN? enough balance? under the daily limit? not flagged as fraud? Each failed check declines the payment with a specific reason.

Pay ₹500→if PIN ok, if balance ok, if limit ok…→Approved / declined
> ₹10L: 30%> ₹7L: 20%> ₹3L: 5%

2. Slabs: tax, delivery charges, discounts

Income-tax slabs, delivery fees by distance and discount tiers are else-if ladders. The order of checks must match the business rules exactly. (Slabs shown here are only an illustration.)

Amount→else-if ladder, highest slab first→Rate
400 Bad Request“email is required”

3. Input validation with guard clauses

API handlers start with a list of guard clauses: if (email == null) return badRequest(…). Bad requests are rejected early and the main logic stays readable.

Request→if invalid → return error→Main logic

4. Feature flags

Companies release new features gradually: if (flags.isEnabled("newCheckout", user)) { … } else { … }. The same code serves both old and new experiences.

User→if flag on → new screen→Safe rollout

5. Time-based rules

“Canteen offer only between 3 and 5 pm”, “late fee after the 10th”, “night charges after 11 pm” are conditions on dates and times, written as ifs.

Now = 4:15 pm→if (hour >= 15 && hour < 17)→Offer applies

Examples are simplified to show where decisions fit. Real rules are more detailed.

7 Run the code

The grading program

public class Main {
    public static void main(String[] args) {
        int marks = 72;
        String grade;
        if (marks >= 90) {
            grade = "A+";
        } else if (marks >= 75) {
            grade = "A";
        } else if (marks >= 60) {
            grade = "B";
        } else if (marks >= 40) {
            grade = "C";
        } else {
            grade = "Fail";
        }
        System.out.println("Marks " + marks + ": Grade " + grade);
    }
}
Marks 72: Grade B
  • String grade;Declared without a value. Every branch assigns it, so javac is satisfied.
  • if (marks >= 90)The strictest check comes first.
  • else if (…)Only checked if all earlier conditions were false.
  • elseCatches everything else, so there's always a grade.
8 Line by line

Follow 72 through the ladder

Notice which lines the tracer visits and which it skips completely.

Worked examples: real problems, solved and traced in memory

Decisions are the heart of business rules. Each program below turns a real rule into if / else if / else. In the trace, watch which lines are skipped: the JVM evaluates a condition and jumps over the branches that don't apply.

Example 1Banking · loans

Personal loan pre-approval

Problem statement

A bank pre-approves a personal loan if the applicant is 21–58 years old, earns at least Rs 25,000 a month and has a credit score of 700 or more. Otherwise it explains the first reason for rejection.

Input
age 35, income 22000, credit score 760
Expected output
Rejected: income below Rs 25,000

Approach

  1. Check each rule in order with if / else if.
  2. The first failing rule gives the reason.
  3. If none fail, approve.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

Example 2Education · grades

Marks to grade

Problem statement

A university converts percentage marks into grades: 90+ O, 75–89 A, 60–74 B, 40–59 C, below 40 F. Grade three students.

Input
marks 82, 39, 90
Expected output
82 -> A
39 -> F
90 -> O

Approach

  1. Test from the highest band down.
  2. Each else if only runs if all earlier tests failed, so lower limits are enough.
  3. Use a helper method so the same rules grade every student.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

Example 3Utilities · billing

Electricity slab billing

Problem statement

Electricity is billed in slabs: the first 100 units at Rs 3, the next 200 units (101–300) at Rs 5, and anything above 300 at Rs 8. Compute the bill for 380 units.

Input
380 units
Expected output
380 units: Rs 1940

Approach

  1. If units ≤ 100: units × 3.
  2. Else if ≤ 300: 100 × 3 + (units − 100) × 5.
  3. Else: full first two slabs + (units − 300) × 8.

Solution: run it live

What happens in memory, step by step

Recorded from the real JVM: press Next to execute one line at a time. Watch method calls push and pop frames on the stack, and objects (numbered #1, #2 …) appear on the heap.

9 Quiz and revision

Check yourself

Quick revision

Lesson 3.1 in one screen

  • Forms: if, if-else, else-if ladder, nested if.
  • Condition must be boolean; = vs == is caught by javac for ints.
  • Ladder: first true condition wins; order from strictest to loosest; end with else.
  • Always use braces; without them only one statement belongs to the if. else pairs with the nearest if.
  • Behind the screen: compare + conditional jump (if_icmplt…) + goto past the other branches.
  • Prefer guard clauses over deep nesting; test boundary values.

Interview and viva questions

What's the difference between if-else-if and multiple separate ifs?

In an else-if ladder, at most one branch runs: checking stops at the first match. With separate if statements, every condition is checked and several blocks can run.

When should you use switch instead of if-else?

When you compare one value against many fixed constants (like menu options or days), switch is clearer and can be faster. For ranges (marks ≥ 60) or complex conditions, if-else is the right tool. Lesson 3.2 covers switch.

What is a guard clause?

An if at the start of a method that handles an invalid or special case and returns immediately, for example if (amount <= 0) return;. It avoids nesting the main logic inside several ifs.

Can an if statement have a semicolon after the condition?

It compiles, but if (x > 5); means “if x > 5, do nothing”, and the following block runs every time. It's a common bug, and IDEs warn about it.

Is the ternary operator a replacement for if-else?

Only for choosing between two values, e.g. String r = marks >= 40 ? "Pass" : "Fail";. For running different statements, or more than two cases, if-else is clearer.

Practice problems

Solve each problem yourself in the live editor first. Then open the solution to compare. The last two are real business rules of the kind you'll write at work.

P1Easy

Even or odd

Given a whole number n, print whether it is even or odd.

Input
n = 17
Expected output
17 is odd
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        int n = 17;
        if (n % 2 == 0) {
            System.out.println(n + " is even");
        } else {
            System.out.println(n + " is odd");
        }
    }
}
17 is odd

How it works: a number is even when dividing by 2 leaves no remainder, so we test n % 2 == 0. Exactly one of two outcomes is possible, so if-else is the right form. (For negative odd numbers, n % 2 is −1, which is still “not 0”, so the code works for them too.)

P2Easy

Largest of three numbers

Given three numbers a, b and c, print the largest.

Input
a = 12, b = 45, c = 29
Expected output
Largest: 45
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        int a = 12, b = 45, c = 29;
        int largest;
        if (a >= b && a >= c) {
            largest = a;
        } else if (b >= c) {
            largest = b;
        } else {
            largest = c;
        }
        System.out.println("Largest: " + largest);
    }
}
Largest: 45

How it works: if a beats both others, it's the answer. Otherwise the answer is either b or c, so one more comparison decides. Using >= means ties are handled correctly. (Later you can simply write Math.max(a, Math.max(b, c)).)

P3Easy

Positive, negative or zero

Print whether n is positive, negative or zero.

Input
n = -8
Expected output
-8 is negative
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        int n = -8;
        if (n > 0) {
            System.out.println(n + " is positive");
        } else if (n < 0) {
            System.out.println(n + " is negative");
        } else {
            System.out.println("The number is zero");
        }
    }
}
-8 is negative

How it works: three possible outcomes need a ladder with two conditions and an else. The else catches the only remaining case, zero, so we don't need to test n == 0.

P4Medium

Vowel, consonant, digit or symbol

Given a character ch, print whether it is a vowel, a consonant, a digit or something else. Treat upper and lower case the same.

Input
ch = 'E'
Expected output
E is a vowel
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        char ch = 'E';
        char lower = Character.toLowerCase(ch);
        if (lower == 'a' || lower == 'e' || lower == 'i' || lower == 'o' || lower == 'u') {
            System.out.println(ch + " is a vowel");
        } else if (lower >= 'a' && lower <= 'z') {
            System.out.println(ch + " is a consonant");
        } else if (ch >= '0' && ch <= '9') {
            System.out.println(ch + " is a digit");
        } else {
            System.out.println(ch + " is a symbol or space");
        }
    }
}
E is a vowel

How it works:

  1. Convert to lowercase once, so we only check five vowels instead of ten.
  2. Check vowels before letters: every vowel is also a letter, so the stricter test must come first.
  3. chars are numbers (Lesson 2.2), so lower >= 'a' && lower <= 'z' is a range check on their codes.
P5Medium

Electricity bill with slabs

A power company charges ₹3 per unit for the first 100 units, ₹5 per unit for the next 100, and ₹8 per unit above 200. Calculate the bill for units.

Input
units = 250
Expected output
Bill for 250 units: Rs 1200
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        int units = 250;
        int bill;
        if (units <= 100) {
            bill = units * 3;
        } else if (units <= 200) {
            bill = 100 * 3 + (units - 100) * 5;
        } else {
            bill = 100 * 3 + 100 * 5 + (units - 200) * 8;
        }
        System.out.println("Bill for " + units + " units: Rs " + bill);
    }
}
Bill for 250 units: Rs 1200

How it works: slab pricing charges each part of the usage at its own rate, not the whole usage at the highest rate. For 250 units: 100 × 3 = 300, plus 100 × 5 = 500, plus 50 × 8 = 400, total 1200. Test the edges too: 100, 101, 200 and 201 units.

P6Medium

Classify a triangle

Given three side lengths, print “Not a triangle” if they can't form one (any two sides must add up to more than the third). Otherwise print Equilateral, Isosceles or Scalene.

Input
a = 5, b = 5, c = 8
Expected output
Isosceles triangle
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        int a = 5, b = 5, c = 8;
        if (a + b <= c || a + c <= b || b + c <= a) {
            System.out.println("Not a triangle");
        } else if (a == b && b == c) {
            System.out.println("Equilateral triangle");
        } else if (a == b || b == c || a == c) {
            System.out.println("Isosceles triangle");
        } else {
            System.out.println("Scalene triangle");
        }
    }
}
Isosceles triangle

How it works: the invalid case is checked first, as a guard. Then the strictest type (all three equal) comes before “any two equal”, because an equilateral triangle would also pass the isosceles test.

P7Business problem

Food delivery fee calculator

A food delivery app charges a delivery fee by these rules, in this order:

  • Members always get free delivery. Orders of ₹499 or more also get free delivery.
  • Otherwise: up to 3 km costs ₹20, up to 7 km costs ₹35, and anything further costs ₹50.
  • A late-night surcharge of ₹15 is added (on paid deliveries) between 11 pm and 5 am.
Input
orderValue = 349, distanceKm = 6.5,
member = false, hour = 23
Expected output
Delivery fee: Rs 50
Show solution and explanation
public class Main {
    public static void main(String[] args) {
        int orderValue = 349;
        double distanceKm = 6.5;
        boolean member = false;
        int hour = 23;                        // 24-hour clock

        int fee;
        if (member || orderValue >= 499) {
            fee = 0;
        } else {
            if (distanceKm <= 3) {
                fee = 20;
            } else if (distanceKm <= 7) {
                fee = 35;
            } else {
                fee = 50;
            }
            boolean lateNight = hour >= 23 || hour < 5;
            if (lateNight) {
                fee = fee + 15;
            }
        }
        System.out.println("Delivery fee: Rs " + fee);
    }
}
Delivery fee: Rs 50

How it works:

  1. The “free” rules come first, joined with ||: either one is enough.
  2. Only paid deliveries go through the distance ladder: 6.5 km falls in the “up to 7 km” slab, ₹35.
  3. Late night wraps around midnight, so it needs ||, not &&: hour 23 or hours 0–4. Writing hour >= 23 && hour < 5 would never be true, a very common real bug.
  4. Naming the condition lateNight makes the rule readable. ₹35 + ₹15 = ₹50.
P8Business problem

Loan pre-eligibility check with reasons

A bank pre-checks personal-loan applicants. Reject with a reason code if any rule fails, checking in this order: age must be 21–60 (AGE); monthly income at least ₹25,000 (INCOME); credit score at least 700 (CREDIT_SCORE); existing EMIs must be at most 40% of income (EMI_TOO_HIGH). Otherwise print “Eligible”. Check two applicants. (The rules are illustrative, not any real bank's.)

Input
Applicant 1: age 27, income 42000,
  score 712, existing EMI 9000
Applicant 2: age 34, income 30000,
  score 745, existing EMI 15000
Expected output
Applicant 1: Eligible
Applicant 2: Rejected (EMI_TOO_HIGH)
Show solution and explanation
public class Main {
    static String check(int age, int income, int score, int emi) {
        if (age < 21 || age > 60) {
            return "Rejected (AGE)";
        }
        if (income < 25_000) {
            return "Rejected (INCOME)";
        }
        if (score < 700) {
            return "Rejected (CREDIT_SCORE)";
        }
        if (emi > income * 0.40) {
            return "Rejected (EMI_TOO_HIGH)";
        }
        return "Eligible";
    }

    public static void main(String[] args) {
        System.out.println("Applicant 1: " + check(27, 42_000, 712, 9_000));
        System.out.println("Applicant 2: " + check(34, 30_000, 745, 15_000));
    }
}
Applicant 1: Eligible Applicant 2: Rejected (EMI_TOO_HIGH)

How it works:

  1. Each rule is a guard clause: if it fails, the method returns immediately with a reason. No deep nesting.
  2. The order of checks matches the business order, so the reported reason is the first rule that failed.
  3. Applicant 2: 40% of ₹30,000 is ₹12,000, and their EMIs are ₹15,000, so they fail the last rule.
  4. Returning a reason code (not just true/false) is how real systems explain decisions to customers and auditors. Methods are covered fully in Module 5.

Real-world scenario questions (asked in company interviews)

Business rules live in if statements, so their bugs cost real money. Decide your answer first, then open the model answer.

E-commerce · discountsFresher

Big orders get the small discount

The rule: 5% off above ₹500, 10% off above ₹1000. Customers spending ₹2,000 complain they only got 5%. The code is if (total > 500) { d = 5; } else if (total > 1000) { d = 10; }. Explain and fix.

The interviewer is checking: do you understand that an else-if ladder stops at the first match?

Show a strong answer

₹2,000 is greater than 500, so the first branch matches and the 1000 check is never reached. The 10% branch is effectively dead code.

  • Reorder from the highest slab down: if (total > 1000) d = 10; else if (total > 500) d = 5; else d = 0;
  • Clarify the exact boundaries with the business (is ₹1000 itself 5% or 10%?) and write them down.
  • Add tests at 499, 500, 501, 1000, 1001 and a large value. Slab rules often move to configuration later.

Avoid: making two separate ifs, where the second overwrites the first. It works by accident and confuses readers.

Security · code review1–3 years

The check that always passed

A login check was written without braces: if (!passwordValid) logFailure(); return deny(); on two lines, with careful indentation. Later someone added a line, and now an important security check after it is never reached. Why do teams insist on braces even for one line?

The interviewer is checking: do you know that indentation means nothing to the compiler, and how style rules prevent real bugs?

Show a strong answer

Without braces, only the first statement belongs to the if. Statements that look indented under it actually run every time. A famous real-world security bug was caused by exactly this kind of mistake, where a duplicated line made later checks unreachable.

  • Always use braces, even for single statements. Most style guides and Checkstyle rules require it.
  • Use the IDE formatter: it re-indents code to match the real structure and exposes the problem.
  • Unit-test both the success and the failure path of every security check.

Avoid saying: “Braces are just style.”

Fintech · loan approval1–3 years

Arrow-shaped code nobody wants to touch

A loan-eligibility method has ifs nested six levels deep (age, income, credit score, existing loans, KYC, city), with else blocks scattered at the bottom. A new rule must be added. How would you restructure it?

The interviewer is checking: do you know guard clauses and how to keep decision logic readable?

Show a strong answer
  • Turn each check into a guard clause that returns immediately with a clear reason: if (age < 21) return reject("AGE");. The happy path ends up at the bottom, unindented.
  • Extract each rule into a well-named method, such as hasAcceptableCreditScore(applicant).
  • Write tests for the current behaviour before refactoring, so nothing changes by accident; then add the new rule as one more guard.
  • If rules change often, consider a rules table or configuration instead of code.

Avoid: adding a seventh level of nesting “because that's how the code is”.

EdTech · exam resultsFresher

Students with exactly 40 marks were failed

The university rule says “40 or more is a pass”. After results were published, students with exactly 40 complained they were marked Fail. The code says if (marks > 40). How did tests miss it, and how do you prevent this class of bug?

The interviewer is checking: do you know boundary-value testing and careful translation of rules into conditions?

Show a strong answer

The rule says “40 or more” (>=), but the code used >. Tests probably used typical values like 25 and 75, never the exact boundary.

  • Fix: if (marks >= PASS_MARK), with the pass mark as a named constant.
  • Add boundary tests: 39, 40, 41, and the extremes 0 and 100.
  • Re-run the result calculation for affected students and communicate the correction.

Avoid: testing only “typical” values. Bugs live at the edges.