Control Flow
So far, every line of your code runs from top to bottom, every single time. Control flow changes that — it lets your program make decisions . Think of it like a traffic intersection: without signals, every car goes straight. With a traffic light, cars stop or go depending on the signal. That's what if , else , and switch do for your code.
Learn Control Flow in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
📋 Before You Start
This lesson builds on what you learned in Lessons 1-3. You should already know how to:
If any of that is fuzzy, go back to Lesson 3: Operators for a quick review.
The if statement is the simplest decision-maker. It checks a condition (something that's either true or false), and if it's true, it runs the code inside the curly braces. If it's false, it skips that code entirely.
Here's the pattern you'll use thousands of times:
🔑 Key point: The condition inside the parentheses () must evaluate to true or false . This is why you learned comparison operators ( > , < , == ) in the last lesson — they produce boolean values that if can use.
A plain if only handles the "yes" case. But what if you want to do something different when the condition is false? That's where else comes in. It's like saying "if this is true, do A; otherwise, do B."
Exactly one block always runs. If the condition is true, the if block runs and the else block is skipped. If the condition is false, the if block is skipped and the else block runs. There's no scenario where both run, or neither runs.
What if you have more than two possibilities? For example, a grade calculator needs to check A, B, C, D, and F — that's five options, not just two. Use else if to chain conditions together:
⚠️ Order matters! Java checks conditions from top to bottom and runs the first match . Once a match is found, ALL remaining else-if/else blocks are skipped. If you put score >= 60 first, a score of 95 would get "D" because 95 >= 60 is also true!
Rule of thumb: Put the most specific (or highest) condition first, then work your way down to the most general. The final else acts as a "catch everything else" safety net.
Sometimes you need to check a condition, and then check another condition inside that. This is called nesting . Think of it like a security checkpoint: first, check if you have a ticket. If yes, then check if it's VIP or regular.
⚠️ Don't nest too deep! If you have 3+ levels of nesting, your code becomes very hard to read. This is called "pyramid of doom" or "arrow code." Instead, use early returns or combine conditions with && :
When you're comparing one variable against many exact values , a switch statement is cleaner than a long if-else-if chain. It's like a vending machine — you press a button (A1, A2, B1), and the machine gives you the matching item.
The #1 bug beginners make with switch is forgetting break . Without it, Java doesn't stop at the matching case — it "falls through" and runs ALL the cases below it too!
💡 Java 14+ Enhanced Switch: Modern Java has a new switch syntax that eliminates the break problem entirely:
The arrow -> syntax doesn't need break and can return a value directly.
Sometimes you just need to pick between two values based on a simple condition. Writing a full if/else for that feels like overkill. The ternary operator is a one-line shortcut:
⚠️ Don't overuse it! The ternary operator is great for simple assignments. But if your logic is complex, use a regular if/else — it's much easier to read and debug. If you're nesting ternaries inside ternaries, that's a code smell.
Each control flow tool has its sweet spot. Using the right one makes your code cleaner and easier to read:
Let's combine everything you've learned into a realistic example. Here's a login system that checks multiple conditions:
Notice how this uses nested if (the failed attempts check inside the else-if), logical AND ( && ), and String comparison with .equals() . This is the kind of real code you'll write in actual applications.
💡 Use early returns to avoid deep nesting. Instead of wrapping everything in if-else, check for the "bad" case first and return early.
💡 Always include default in switch statements — it catches unexpected values and makes debugging easier.
💡 Use constants or enums for switch values instead of "magic strings" — prevents typos and enables auto-complete.
💡 Combine conditions with && and || instead of deeply nesting if statements.
💡 Keep conditions simple — if a condition is complex, extract it into a boolean variable with a descriptive name:
Your programs can now make intelligent decisions! You've learned if-else chains, switch statements, the ternary operator, nested conditions, and when to use each one. You even built a real-world ticket pricing system!
Next up: Loops — learn to repeat actions with for, while, and do-while loops to process data, build patterns, and automate repetitive tasks.
Practice quiz
What must the condition inside an if statement's parentheses evaluate to?
- A number
- A String
- true or false (boolean)
- An array
Answer: true or false (boolean). An if condition must be a boolean — it evaluates to either true or false.
In an if-else, how many of the two blocks run?
- Exactly one always runs
- Both always run
- Neither runs
- It depends on the loop
Answer: Exactly one always runs. Exactly one block runs: the if block if the condition is true, otherwise the else block.
In an else-if chain, what happens after the first matching condition runs?
- All remaining blocks also run
- The program crashes
- It loops back to the top
- The remaining else-if/else blocks are skipped
Answer: The remaining else-if/else blocks are skipped. Java runs the first matching block, then skips all remaining else-if and else blocks.
In a switch statement, what happens if you forget break in a matching case?
- A compile error
- Execution falls through into the cases below
- Nothing runs
- Only that case runs
Answer: Execution falls through into the cases below. Without break, execution 'falls through' and runs the following cases too.
What does this print? int num=2; switch(num){ case 1: System.out.print("One "); case 2: System.out.print("Two "); case 3: System.out.print("Three "); }
- Two Three
- Two
- One Two Three
- Three
Answer: Two Three. Matching starts at case 2 and, with no break, falls through to case 3, printing 'Two Three '.
What is the ternary operator's syntax?
- if ? then : else
- condition : true ? false
- condition ? valueIfTrue : valueIfFalse
- value ? value ? value
Answer: condition ? valueIfTrue : valueIfFalse. The ternary form is condition ? valueIfTrue : valueIfFalse — a one-line if/else.
Which tool is best for comparing one variable against many exact values?
- A for loop
- A switch statement
- A ternary operator
- A nested if only
Answer: A switch statement. A switch is the cleanest way to compare one variable against many exact values.
What does String status = (age >= 18) ? "Adult" : "Minor"; assign when age is 15?
- "Adult"
- null
- An error
- "Minor"
Answer: "Minor". 15 >= 18 is false, so the ternary returns the false branch, "Minor".
What is wrong with: if (x > 5); { System.out.println("hi"); }
- Nothing
- The stray semicolon makes the if do nothing; the block always runs
- It will not compile
- It prints twice
Answer: The stray semicolon makes the if do nothing; the block always runs. The semicolon ends the if with an empty body, so the following block always runs regardless of x.
In the enhanced (arrow) switch like case "x" -> result, do you need break?
- Yes, always
- Only for the default
- No, the arrow form does not fall through
- Only for Strings
Answer: No, the arrow form does not fall through. The Java 14+ arrow syntax doesn't fall through, so no break is needed.