Java Academy

Master Java Development

Menu

Core Java

Servlets

JDBC

Microservices

Build Tools

APIs

Core Java · Lesson 4

Control Flow Statements

Making Decisions with Control Flow

Control flow statements direct the order in which your code executes — they let you run different code based on conditions, repeat actions, and skip sections. Without them, every Java program would run line-by-line from top to bottom with no decision-making. Control flow is the foundation of responsive, intelligent programs that adapt to different inputs and situations.

Conditional Statements: if, else if, and else

The if statement executes a block of code only if a condition is true. else if lets you test multiple conditions in sequence, and else catches anything that didn't match previous conditions. Each condition is a boolean expression that evaluates to true or false. Think of it as asking questions: "Is the score above 90? If yes, print A. If no, is it above 80? If yes, print B."

public class ConditionalStatements {
    public static void main(String[] args) {
        int score = 85;
        
        // Single if
        if (score >= 90) {
            System.out.println("Grade: A");
        }
        
        // if-else if-else chain
        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");
        } else {
            System.out.println("Grade: F");
        }
        
        // Nested conditions
        int age = 25;
        if (age >= 18) {
            if (score >= 80) {
                System.out.println("Adult with excellent score!");
            } else {
                System.out.println("Adult with average score.");
            }
        }
    }
}

The switch Statement: Cleaner Multi-Branch Logic

When you have many conditions checking the same variable, a switch statement is cleaner than a long if-else chain. Each case represents a possible value, and default catches anything not explicitly matched. Remember to include break statements to prevent "fall-through" (unintended execution of following cases).

public class SwitchExample {
    public static void main(String[] args) {
        int dayNumber = 3;
        String dayName;
        
        switch (dayNumber) {
            case 1:
                dayName = "Monday";
                break;  // exit the switch
            case 2:
                dayName = "Tuesday";
                break;
            case 3:
                dayName = "Wednesday";
                break;
            case 4:
                dayName = "Thursday";
                break;
            case 5:
                dayName = "Friday";
                break;
            default:
                dayName = "Weekend";  // if dayNumber isn't 1-5
        }
        
        System.out.println("Day " + dayNumber + " is " + dayName);
    }
}

Looping: for, while, and do-while

Loops repeat code multiple times, essential for processing collections or performing repetitive tasks. The for loop is best when you know how many iterations you need. The while loop repeats while a condition is true (unknown iteration count). The do-while loop runs at least once, then checks the condition. Each has a specific use case.

public class LoopExamples {
    public static void main(String[] args) {
        // for loop: known iterations (1 to 5)
        System.out.println("Traditional for loop:");
        for (int i = 1; i <= 5; i++) {
            System.out.println("Count: " + i);
        }
        
        // for-each loop: iterating over arrays/collections
        System.out.println("\nFor-each loop:");
        String[] fruits = {"Apple", "Banana", "Cherry"};
        for (String fruit : fruits) {
            System.out.println("Fruit: " + fruit);
        }
        
        // while loop: unknown iterations
        System.out.println("\nWhile loop:");
        int counter = 0;
        while (counter < 3) {
            System.out.println("Counter: " + counter);
            counter++;
        }
        
        // do-while: executes at least once
        System.out.println("\nDo-while loop:");
        int num = 0;
        do {
            System.out.println("Number: " + num);
            num++;
        } while (num < 3);
    }
}

Loop Control: break and continue

break exits a loop immediately, while continue skips to the next iteration. These statements give you fine-grained control over loop execution. Use break to exit early when you find what you're looking for; use continue to skip processing under certain conditions without exiting the loop.

public class LoopControl {
    public static void main(String[] args) {
        // break: exit loop when condition is met
        System.out.println("Using break:");
        for (int i = 1; i <= 10; i++) {
            if (i == 5) {
                System.out.println("Found 5, exiting!");
                break;  // exit the loop
            }
            System.out.println(i);
        }
        
        // continue: skip to next iteration
        System.out.println("\nUsing continue:");
        for (int i = 1; i <= 5; i++) {
            if (i == 3) {
                System.out.println("Skipping 3...");
                continue;  // jump to next iteration
            }
            System.out.println("Processing: " + i);
        }
    }
}

Logical Operators: AND, OR, and NOT

Logical operators combine multiple conditions: && (AND) means both must be true, || (OR) means at least one must be true, and ! (NOT) reverses the result. These operators let you express complex decision logic concisely.

public class LogicalOperators {
    public static void main(String[] args) {
        int age = 25;
        int income = 50000;
        
        // AND (&&): both conditions must be true
        if (age >= 18 && income >= 30000) {
            System.out.println("Eligible for premium membership");
        }
        
        // OR (||): at least one condition must be true
        if (age < 18 || income < 20000) {
            System.out.println("Eligible for discount");
        }
        
        // NOT (!): reverses the condition
        boolean isStudent = false;
        if (!isStudent) {
            System.out.println("You are not a student");
        }
        
        // Complex conditions
        if ((age >= 18 && age <= 65) || (income > 100000)) {
            System.out.println("Welcome!");
        }
    }
}

Common Mistake: Confusing = (assignment) with == (comparison). In an if statement, if (score = 90) assigns 90 to score instead of checking if it equals 90. Always use == for comparison. Modern IDEs warn about this, but it's an easy mistake to make.

Best Practices for Control Flow

  • Keep conditions simple and readable: break complex logic into variables or separate methods
  • Use switch for multiple exact matches: it's clearer than many if-else statements
  • Prefer for-each loops for iterating collections; they're simpler and safer
  • Avoid deeply nested conditions: refactor or extract methods to reduce nesting
  • Use meaningful boolean variable names: isActive, hasPermission are clearer than x, flag
  • Always include break in switch cases to prevent accidental fall-through

Real-World Example: E-Commerce Order Processing

An online store uses control flow to process customer orders: an if statement checks if inventory is available; a switch statement determines shipping method (standard, express, overnight); a for-each loop iterates through cart items applying discounts. A while loop retries payment processing up to 3 times if the gateway times out. Logical operators combine checks like (hasInventory && isPaymentValid && customerAgeValid) before processing. This layered decision-making ensures orders are handled correctly and customers get proper feedback at each stage.

Quiz Check

Quick Knowledge Test

Loading quiz questions...