Skip to lesson
CodeLangs AISoftware Training Institute
Decision Making and Control Flow in Java

Chapter 6 · Java Control Flow

Decision Making and Control Flow in Java

Master decision making and control flow in Java, including if, if-else, if-else-if, nested conditions, multiple conditions with short-circuit evaluation, traditional and modern switch, break, fall-through, yield, the ternary operator, and choosing between if and switch.

  • 9,169words
  • 42min read
  • 20quiz items
  • 16practice tools

Java programs become useful when they can make decisions.

Think about software you use every day.

A banking application may need to decide:

Is the account balance sufficient for this withdrawal?

An e-commerce application may need to decide:

Is the customer eligible for a discount?

A login system may need to decide:

Are the username and password valid?

An examination system may need to decide:

Did the student pass, fail, or earn distinction?

Until now, imagine that Java simply executed every statement from top to bottom.

Java
System.out.println("Step 1");
System.out.println("Step 2");
System.out.println("Step 3");

The flow is predictable:

Output
Step 1
  ↓
Step 2
  ↓
Step 3

But real applications cannot always execute every statement.

Sometimes one path should run.

Sometimes another path should run.

Sometimes nothing should happen.

Sometimes one of several possible paths must be selected.

That ability to control which statements execute and in what order they execute is the foundation of this chapter.

The supplied chapter specifically covers Control Flow, if, if-else, if-else-if, nested conditions, multiple conditions, switch, traditional and modern switch syntax, yield, break, fall-through, the ternary operator, and choosing between if and switch.


1. First Understand Program Flow#

Before learning if or switch, we need one small idea.

What is flow?#

A program consists of instructions.

Normally Java executes them sequentially.

Java
public class Main {
    public static void main(String[] args) {
        System.out.println("Start");
        System.out.println("Processing");
        System.out.println("End");
    }
}

Output:

Output
Start
Processing
End

The execution flow is:

Output
main() starts
    ↓
print "Start"
    ↓
print "Processing"
    ↓
print "End"
    ↓
main() finishes

This is called sequential execution.

Now imagine:

Java
int balance = 500;
int withdrawal = 1000;

Should the application always execute the withdrawal?

Obviously not.

It must first ask:

Output
Is balance >= withdrawal?

Now our program requires a decision.

That brings us to control flow.


2. Control Flow#

Simple Meaning#

Control flow is the order in which statements in a program are executed.

Without special control structures, statements normally execute from top to bottom.

Java gives us constructs that can change this flow.

For this chapter, the most important are:

Output
Control Flow
│
├── Decision Making
│   ├── if
│   ├── if-else
│   ├── if-else-if
│   ├── nested if
│   ├── switch
│   └── ternary operator
│
└── Flow Transfer
    └── break

Loops also control program flow, but they belong to another chapter.


3. The Boolean Condition Behind Decision Making#

Before we write an if, there is one concept we must understand.

Java needs a way to answer questions such as:

Output
Is age at least 18?
Is balance greater than zero?
Is password valid?
Is user logged in?

Such questions ultimately produce either:

Output
true

or:

Output
false

Java represents these values with the primitive type:

Java
boolean

Example:

Java
boolean loggedIn = true;
boolean paymentCompleted = false;

Comparison expressions also produce boolean values.

Java
int age = 25;

boolean result = age >= 18;

System.out.println(result);

Output:

Output
true

Here:

Java
age >= 18

is itself a boolean expression.

That is exactly what an if statement needs.


4. Java Does Not Use “Truthy” and “Falsy” Values#

This is an important Java rule.

Some programming languages allow code such as:

Output
if (1)

or:

Output
if ("hello")

Java does not.

The condition of an if must evaluate to boolean.

This is valid:

Java
int age = 25;

if (age >= 18) {
    System.out.println("Adult");
}

This is invalid:

Java
int age = 25;

if (age) {
    System.out.println("Adult");
}

The second example does not compile because age is an int, not a boolean.

Rule#

Output
Java if condition
        ↓
must evaluate to
        ↓
boolean
        ↓
true or false

5. Why Do We Need if?#

Suppose we have:

Java
int age = 16;

System.out.println("You can vote.");

This program prints:

Output
You can vote.

But the statement is incorrect for a 16-year-old.

What do we really want?

Output
IF age is at least 18
    allow voting

Java gives us exactly this structure.


6. if Statement#

Mental Model#

Think of if as a gate.

Output
             Condition
                 ↓
            ┌─────────┐
            │ true ?  │
            └────┬────┘
                 │
          ┌──────┴──────┐
        true           false
          │              │
          ↓              ↓
      Run block        Skip block

Syntax#

Java
if (condition) {
    // Statements executed when condition is true
}

The condition must evaluate to true or false.


7. First if Example#

Java
public class VotingExample {
    public static void main(String[] args) {
        int age = 20;

        if (age >= 18) {
            System.out.println("You are eligible to vote.");
        }

        System.out.println("Program finished.");
    }
}

Output:

Output
You are eligible to vote.
Program finished.

Now change:

Java
int age = 15;

Output:

Output
Program finished.

Why?

Because:

Java
age >= 18

becomes:

Output
15 >= 18

which is:

Output
false

Therefore Java skips the body of the if.


8. Execution Flow of if#

Consider:

Java
int temperature = 35;

if (temperature > 30) {
    System.out.println("It is hot.");
}

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

Execution:

Output
temperature = 35
      ↓
temperature > 30?
      ↓
    true
      ↓
print "It is hot."
      ↓
print "Done."

If:

Java
temperature = 20;

then:

Output
temperature = 20
      ↓
temperature > 30?
      ↓
    false
      ↓
skip if block
      ↓
print "Done."

Notice something important:

if controls only its own block.

Code after the block continues normally.


9. Curly Braces and if#

Java permits a single statement without braces.

Java
if (age >= 18)
    System.out.println("Adult");

This compiles.

But consider:

Java
if (age >= 18)
    System.out.println("Adult");
    System.out.println("Access granted");

Only the first statement belongs to the if.

Java effectively sees:

Java
if (age >= 18) {
    System.out.println("Adult");
}

System.out.println("Access granted");

This can create serious bugs.

Preferred Production Style#

Use braces.

Java
if (age >= 18) {
    System.out.println("Adult");
    System.out.println("Access granted");
}

Even when there is only one statement:

Java
if (age >= 18) {
    System.out.println("Adult");
}

It is easier to maintain and harder to accidentally break later.


10. if with Boolean Variables#

You do not always need to write a comparison directly.

Java
boolean loggedIn = true;

if (loggedIn) {
    System.out.println("Welcome back.");
}

This is already a boolean expression.

You sometimes see:

Java
if (loggedIn == true) {
    System.out.println("Welcome back.");
}

It works, but is unnecessarily verbose.

Prefer:

Java
if (loggedIn) {
    System.out.println("Welcome back.");
}

For the opposite condition:

Java
if (!loggedIn) {
    System.out.println("Please log in.");
}

! means logical NOT.

Output
true  → false
false → true

11. A New Problem Appears#

if works when we want:

Output
If condition is true → do something.

But consider a login application.

We want:

Output
If password is correct
    show dashboard
otherwise
    show error

With only if, we might write:

Java
if (passwordCorrect) {
    System.out.println("Login successful.");
}

if (!passwordCorrect) {
    System.out.println("Invalid password.");
}

It works, but both conditions represent two opposite sides of the same decision.

Java gives us a cleaner structure.


12. if-else#

Mental Model#

Output
               Condition
                   ↓
             ┌──────────┐
             │ true ?   │
             └────┬─────┘
                  │
        ┌─────────┴─────────┐
      true                false
        │                    │
        ↓                    ↓
    if block            else block
        │                    │
        └─────────┬──────────┘
                  ↓
            continue program

Syntax#

Java
if (condition) {
    // Runs when condition is true
} else {
    // Runs when condition is false
}

Exactly one branch executes.


13. if-else Example#

Java
public class LoginExample {
    public static void main(String[] args) {
        boolean passwordCorrect = false;

        if (passwordCorrect) {
            System.out.println("Login successful.");
        } else {
            System.out.println("Invalid password.");
        }
    }
}

Output:

Output
Invalid password.

If:

Java
boolean passwordCorrect = true;

output becomes:

Output
Login successful.

The important rule is:

Output
if condition true
    ↓
execute if
    ↓
skip else

if condition false
    ↓
skip if
    ↓
execute else

Both cannot execute during one evaluation of the same if-else.


14. Practical Example — Even or Odd#

We want to determine whether an integer is even.

A number is even when its remainder after division by 2 is zero.

The remainder operator is:

Java
%

Example:

Java
10 % 2

produces:

Output
0

So:

Java
public class EvenOddExample {
    public static void main(String[] args) {
        int number = 17;

        if (number % 2 == 0) {
            System.out.println("Even");
        } else {
            System.out.println("Odd");
        }
    }
}

Output:

Output
Odd

15. = Versus ==#

This is one of the most important beginner mistakes.

= means assignment.

Java
int age = 25;

It means:

Put 25 into age.

== means equality comparison for primitive values.

Java
age == 25

It asks:

Is age equal to 25?

For boolean variables, this can cause confusing code.

Java
boolean active = false;

if (active = true) {
    System.out.println("Active");
}

This compiles.

Why?

Because:

Java
active = true

assigns true to active.

The assignment expression itself evaluates to true.

Therefore the body executes.

That is usually a logical bug.

Prefer:

Java
if (active) {
    System.out.println("Active");
}

16. What If We Have More Than Two Choices?#

Suppose students receive grades:

Output
90+  → A
80+  → B
70+  → C
60+  → D
below 60 → F

An if-else handles two branches.

But here we need several mutually exclusive branches.

We need another form.


17. if-else-if Ladder#

Syntax#

Java
if (condition1) {
    // Branch 1
} else if (condition2) {
    // Branch 2
} else if (condition3) {
    // Branch 3
} else {
    // Fallback branch
}

Java evaluates conditions from top to bottom.

The first true branch executes.

Then the rest of the ladder is skipped.


18. Grade Example#

Java
public class GradeExample {
    public static void main(String[] args) {
        int marks = 84;

        if (marks >= 90) {
            System.out.println("Grade A");
        } else if (marks >= 80) {
            System.out.println("Grade B");
        } else if (marks >= 70) {
            System.out.println("Grade C");
        } else if (marks >= 60) {
            System.out.println("Grade D");
        } else {
            System.out.println("Grade F");
        }
    }
}

Output:

Output
Grade B

Let's trace it.

Output
marks = 84

84 >= 90 ?
false
   ↓
84 >= 80 ?
true
   ↓
print Grade B
   ↓
STOP checking remaining branches

Java does not continue to test:

Java
84 >= 70

even though that would also be true.

Why?

Because an if-else-if ladder selects the first matching branch.


19. Order Matters in if-else-if#

Consider this incorrect logic:

Java
int marks = 95;

if (marks >= 60) {
    System.out.println("Grade D");
} else if (marks >= 70) {
    System.out.println("Grade C");
} else if (marks >= 80) {
    System.out.println("Grade B");
} else if (marks >= 90) {
    System.out.println("Grade A");
}

What happens?

The first condition:

Java
marks >= 60

is already true.

So output becomes:

Output
Grade D

even though 95 should be Grade A.

Preferred Ordering for Threshold Conditions#

Usually check from most restrictive/highest boundary toward the broader/lower ones.

Java
if (marks >= 90) {
    System.out.println("Grade A");
} else if (marks >= 80) {
    System.out.println("Grade B");
} else if (marks >= 70) {
    System.out.println("Grade C");
} else if (marks >= 60) {
    System.out.println("Grade D");
} else {
    System.out.println("Grade F");
}

20. Boundary Values#

Decision-making bugs often appear at boundaries.

Suppose:

Output
Adult = age 18 or above

Correct:

Java
if (age >= 18) {
    System.out.println("Adult");
}

Incorrect for the requirement:

Java
if (age > 18) {
    System.out.println("Adult");
}

With the second version:

Output
age = 18

does not pass.

Boundary operators matter:

Output
>   greater than
>=  greater than or equal
<   less than
<=  less than or equal
==  equal
!=  not equal

In production systems, many bugs come from choosing the wrong boundary operator.


21. Input Validation Before Classification#

Suppose marks should legally be between 0 and 100.

This code:

Java
int marks = 150;

if (marks >= 90) {
    System.out.println("Grade A");
}

prints:

Output
Grade A

But 150 is invalid input.

A robust decision tree should validate first.

Java
int marks = 150;

if (marks < 0 || marks > 100) {
    System.out.println("Invalid marks");
} else if (marks >= 90) {
    System.out.println("Grade A");
} else if (marks >= 80) {
    System.out.println("Grade B");
} else if (marks >= 70) {
    System.out.println("Grade C");
} else if (marks >= 60) {
    System.out.println("Grade D");
} else {
    System.out.println("Grade F");
}

This introduces ||, which we will understand properly in the Multiple Conditions section.


22. Another Problem — A Decision Inside a Decision#

Imagine an ATM.

First:

Output
Is the PIN correct?

Only if the PIN is correct should we ask:

Output
Is the requested amount within the balance?

The second decision belongs inside the first decision.

This gives us nested if.


23. Nested if#

A nested if is simply an if inside another if, else if, or else block.

Java
if (condition1) {
    if (condition2) {
        // Executes only when both conditions reach this point
    }
}

Example:

Java
public class AtmExample {
    public static void main(String[] args) {
        boolean pinCorrect = true;
        double balance = 5000;
        double amount = 1200;

        if (pinCorrect) {
            if (amount <= balance) {
                System.out.println("Withdrawal approved.");
            } else {
                System.out.println("Insufficient balance.");
            }
        } else {
            System.out.println("Invalid PIN.");
        }
    }
}

Output:

Output
Withdrawal approved.

24. Nested if Execution#

Output
PIN correct?
   │
   ├── no → Invalid PIN
   │
   └── yes
         ↓
    amount <= balance?
         │
         ├── yes → Withdrawal approved
         │
         └── no → Insufficient balance

The inner if is not even evaluated unless Java first enters the outer block.


25. When Nested if Becomes Too Deep#

This is technically valid:

Java
if (loggedIn) {
    if (active) {
        if (emailVerified) {
            if (hasPermission) {
                System.out.println("Access granted");
            }
        }
    }
}

But deep nesting makes code harder to read.

This is sometimes called the arrow anti-pattern because indentation keeps moving to the right.

Output
if
  if
    if
      if
        business logic

Production code often benefits from:

  • combining conditions when they represent one decision,
  • guard clauses,
  • extracting meaningful methods.

For example:

Java
if (loggedIn && active && emailVerified && hasPermission) {
    System.out.println("Access granted");
}

Whether this is better depends on whether all conditions belong to the same logical decision.


26. Multiple Conditions#

Real requirements rarely depend on one condition.

For example:

Allow loan application only if age is at least 21 and monthly income is at least ₹30,000.

We need logical operators.

The most important are:

Output
&&  logical AND
||  logical OR
!   logical NOT

27. Logical AND — &&#

&& means:

Both sides must be true.

Truth table:

LeftRightLeft && Right
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

Example:

Java
int age = 30;
double income = 50000;

if (age >= 21 && income >= 30000) {
    System.out.println("Eligible to apply.");
}

Both conditions are true.

Therefore the combined condition is true.


28. Logical OR — ||#

|| means:

At least one side must be true.
LeftRightLeft || Right
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

Example:

Java
boolean admin = false;
boolean manager = true;

if (admin || manager) {
    System.out.println("Access allowed.");
}

Output:

Output
Access allowed.

Only one of the two conditions needs to be true.


29. Logical NOT — !#

! reverses a boolean.

Output
!true  → false
!false → true

Example:

Java
boolean accountBlocked = false;

if (!accountBlocked) {
    System.out.println("Transaction allowed.");
}

Since:

Java
accountBlocked

is false:

Java
!accountBlocked

is true.


30. Combining Multiple Conditions#

Java
int age = 28;
boolean verified = true;
boolean blocked = false;

if (age >= 18 && verified && !blocked) {
    System.out.println("User can continue.");
}

This means:

Output
age at least 18
AND
verified
AND
not blocked

Every part must be true.


31. Parentheses Make Complex Conditions Clearer#

Consider:

Java
if (premium || admin && active) {
    System.out.println("Access granted");
}

Java operator precedence applies.

&& is evaluated before ||.

So Java interprets it like:

Java
if (premium || (admin && active)) {
    System.out.println("Access granted");
}

If your business rule is:

Output
User must be active
AND
user must be either premium or admin

you need:

Java
if ((premium || admin) && active) {
    System.out.println("Access granted");
}

These conditions mean different things.

In production code, explicit parentheses often improve readability even when precedence rules technically make them unnecessary.


32. Short-Circuit Evaluation#

This concept is extremely important.

Consider:

Java
conditionA && conditionB

If conditionA is already false, the whole expression can never become true.

Therefore Java does not need to evaluate conditionB.

This behavior is called short-circuit evaluation.

For &&:

Output
false && anything
      ↓
false

For ||:

Output
true || anything
     ↓
true

33. Why Short-Circuiting Matters#

Suppose:

Java
String name = null;

This is dangerous:

Java
if (name.length() > 0) {
    System.out.println("Name provided");
}

Calling:

Java
name.length()

when name is null throws NullPointerException.

Instead:

Java
if (name != null && name.length() > 0) {
    System.out.println("Name provided");
}

Execution when name == null:

Output
name != null
    ↓
false
    ↓
&& already knows final answer is false
    ↓
name.length() is NOT evaluated

Therefore we avoid the null dereference.

A more expressive modern style is:

Java
if (name != null && !name.isEmpty()) {
    System.out.println("Name provided");
}

34. Order of Conditions Can Matter#

Correct:

Java
if (name != null && !name.isEmpty()) {
    System.out.println(name);
}

Dangerous:

Java
if (!name.isEmpty() && name != null) {
    System.out.println(name);
}

If name is null, Java evaluates:

Java
!name.isEmpty()

first.

The exception occurs before it ever checks:

Java
name != null

Rule#

When using short-circuiting for safety:

Output
safe/precondition check first
        ↓
operation that depends on it second

35. && Versus & With Booleans#

Java also permits:

Java
&

with boolean operands.

But it does not short-circuit.

Example:

Java
boolean result = false & expensiveCheck();

expensiveCheck() still executes.

With:

Java
boolean result = false && expensiveCheck();

the method is skipped.

Similarly:

Java
|

can operate on booleans without short-circuiting, while:

Java
||

short-circuits.

For normal boolean decision logic, && and || are generally the expected operators.

& and | also have bitwise meanings for integer types.


36. Multiple Separate if Statements vs if-else-if#

These two structures are not equivalent.

Separate if#

Java
int number = 10;

if (number > 0) {
    System.out.println("Positive");
}

if (number % 2 == 0) {
    System.out.println("Even");
}

Output:

Output
Positive
Even

Both conditions are independently evaluated.

if-else-if#

Java
int number = 10;

if (number > 0) {
    System.out.println("Positive");
} else if (number % 2 == 0) {
    System.out.println("Even");
}

Output:

Output
Positive

Once the first condition is true, the second is skipped.

Decision Rule#

Use separate if statements when multiple independent conditions may all need to execute.

Use if-else-if when the branches represent mutually exclusive alternatives and normally only one should execute.


37. A New Kind of Decision Problem#

Now consider a menu:

Output
1 → Create Account
2 → Deposit
3 → Withdraw
4 → Check Balance
5 → Exit

We could write:

Java
if (choice == 1) {
    // ...
} else if (choice == 2) {
    // ...
} else if (choice == 3) {
    // ...
} else if (choice == 4) {
    // ...
} else if (choice == 5) {
    // ...
}

This works.

But all conditions compare one expression against several exact values.

That is exactly the type of problem for which switch is useful.


38. switch#

A switch selects a branch based on the value of an expression.

Traditional mental model:

Output
                   choice
                     ↓
          ┌──────────┼──────────┐
          ↓          ↓          ↓
        case 1     case 2     case 3
          ↓          ↓          ↓
        action     action     action
                     ...
                     ↓
                  default

Traditional syntax:

Java
switch (expression) {
    case value1:
        // statements
        break;

    case value2:
        // statements
        break;

    default:
        // fallback
}

39. First Traditional switch#

Java
public class MenuExample {
    public static void main(String[] args) {
        int choice = 2;

        switch (choice) {
            case 1:
                System.out.println("Create Account");
                break;

            case 2:
                System.out.println("Deposit");
                break;

            case 3:
                System.out.println("Withdraw");
                break;

            case 4:
                System.out.println("Check Balance");
                break;

            case 5:
                System.out.println("Exit");
                break;

            default:
                System.out.println("Invalid choice");
        }
    }
}

Output:

Output
Deposit

40. How Traditional switch Executes#

For:

Java
choice = 2;

conceptually:

Output
switch(choice)
      ↓
Is it case 1?
      ↓ no
Is it case 2?
      ↓ yes
execute case 2
      ↓
break
      ↓
leave switch

41. What is case?#

Each case identifies a possible matching value.

Java
case 1:

means:

If the switch selector matches 1, begin executing here.

Example:

Java
String role = "ADMIN";

switch (role) {
    case "ADMIN":
        System.out.println("Administrator");
        break;

    case "USER":
        System.out.println("Normal user");
        break;

    default:
        System.out.println("Unknown role");
}

Output:

Output
Administrator

42. What is default?#

default is the fallback branch.

It executes when no matching case is selected.

Java
int choice = 99;

switch (choice) {
    case 1:
        System.out.println("One");
        break;

    case 2:
        System.out.println("Two");
        break;

    default:
        System.out.println("Unknown");
}

Output:

Output
Unknown

default is similar in purpose to the final else in an if-else-if ladder.

It is optional syntactically, although whether omitting it is appropriate depends on the requirement.


43. Which Types Can Traditional switch Use?#

Traditional Java switch supports integral-style types such as:

  • byte
  • short
  • char
  • int
  • corresponding wrapper types
  • enum
  • String since Java 7

It does not traditionally support selectors such as:

Java
long
float
double
boolean

Example with char:

Java
char grade = 'A';

switch (grade) {
    case 'A':
        System.out.println("Excellent");
        break;

    case 'B':
        System.out.println("Good");
        break;

    default:
        System.out.println("Other grade");
}

44. Case Labels Must Be Compatible Constants#

Traditional case labels are not arbitrary runtime conditions.

This is the kind of usage switch is designed for:

Java
int day = 2;

switch (day) {
    case 1:
        System.out.println("Monday");
        break;

    case 2:
        System.out.println("Tuesday");
        break;
}

It is not a replacement for range expressions such as:

Output
age >= 18
salary > 50000
score >= 90

Those usually fit if better.


45. Why Is break Used?#

Now we encounter another concept.

Suppose a matching case begins executing.

With traditional colon-style switch, Java does not automatically stop after that case.

It continues into following statements unless control leaves the switch.

break tells Java:

Stop this switch and continue after it.

Example:

Java
switch (choice) {
    case 1:
        System.out.println("One");
        break;

    case 2:
        System.out.println("Two");
        break;
}

When case 1 executes, break exits the switch before case 2's statements run.


46. break#

In this chapter, the important use is breaking out of traditional switch.

Output
matched case
    ↓
execute statements
    ↓
break
    ↓
exit switch
    ↓
continue after switch

Example:

Java
int value = 1;

switch (value) {
    case 1:
        System.out.println("Matched");
        break;

    default:
        System.out.println("Not matched");
}

System.out.println("After switch");

Output:

Output
Matched
After switch

47. What Happens If We Forget break?#

Now we arrive at one of the most famous switch behaviors.

Consider:

Java
int value = 1;

switch (value) {
    case 1:
        System.out.println("One");

    case 2:
        System.out.println("Two");

    case 3:
        System.out.println("Three");

    default:
        System.out.println("Other");
}

Prediction moment:

What do you think prints?

Not only:

Output
One

Instead:

Output
One
Two
Three
Other

Why?

Once Java matches case 1, execution begins there and continues sequentially through subsequent labels.

This behavior is called fall-through.


48. Fall-Through Behavior#

Traditional switch:

Output
case matched
    ↓
run statements
    ↓
no break?
    ↓
continue into next case
    ↓
continue...

Example:

Java
int value = 2;

switch (value) {
    case 1:
        System.out.println("One");

    case 2:
        System.out.println("Two");

    case 3:
        System.out.println("Three");
        break;

    default:
        System.out.println("Other");
}

Output:

Output
Two
Three

Java begins at matching case 2.

Because there is no break after case 2, execution falls into case 3.

The break after case 3 then exits.


49. Intentional Fall-Through#

Fall-through is not always a bug.

Sometimes several values should perform the same action.

Traditional syntax:

Java
int month = 2;

switch (month) {
    case 12:
    case 1:
    case 2:
        System.out.println("Winter");
        break;

    case 3:
    case 4:
    case 5:
        System.out.println("Spring");
        break;

    default:
        System.out.println("Other season");
}

For month 2, output:

Output
Winter

Here cases 12, 1, and 2 intentionally share one block.

However, accidental fall-through is a common source of bugs.


50. Traditional Switch with Strings#

Java
public class RoleExample {
    public static void main(String[] args) {
        String role = "ADMIN";

        switch (role) {
            case "ADMIN":
                System.out.println("Full access");
                break;

            case "EDITOR":
                System.out.println("Edit access");
                break;

            case "VIEWER":
                System.out.println("Read-only access");
                break;

            default:
                System.out.println("Unknown role");
        }
    }
}

String matching in a switch uses string value equality semantics.

But there is an important edge case.


51. Null and Traditional Switch#

Consider:

Java
String role = null;

switch (role) {
    case "ADMIN":
        System.out.println("Admin");
        break;

    default:
        System.out.println("Unknown");
}

In traditional Java switch semantics, switching on a null selector causes NullPointerException.

default does not mean:

Handle null automatically.

default means:

Handle a non-matching selector value.

If null is possible and your Java/version-specific switch form does not explicitly handle it, validate first.

Java
if (role == null) {
    System.out.println("Role is missing");
} else {
    switch (role) {
        case "ADMIN":
            System.out.println("Admin");
            break;

        default:
            System.out.println("Unknown");
    }
}

Later Java versions introduced pattern-matching enhancements to switch, including explicit null-related capabilities in appropriate syntax, but that is a separate advanced topic and should not be mixed into the basic traditional-switch model.


52. Another Limitation of Traditional switch#

Suppose we want to assign a description.

Traditional code might look like:

Java
int day = 2;
String name;

switch (day) {
    case 1:
        name = "Monday";
        break;

    case 2:
        name = "Tuesday";
        break;

    case 3:
        name = "Wednesday";
        break;

    default:
        name = "Unknown";
}

This works.

But notice the repetition:

Output
name =
break
name =
break
name =
break

Wouldn't it be cleaner if the switch itself could produce a value?

Modern Java provides that ability.


53. Traditional Switch vs Switch Expression#

Traditional switch was historically a statement.

It primarily controlled execution.

Modern Java also provides switch expressions.

An expression produces a value.

For example:

Java
int result = 10 + 20;

10 + 20 produces the value 30.

Similarly, a switch expression can produce a value.

Java
String dayName = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    case 3 -> "Wednesday";
    default -> "Unknown";
};

The selected branch produces the value assigned to dayName.


54. Java Version Note for Switch Expressions#

This distinction matters in interviews and real projects.

The modern switch-expression feature went through preview releases and became a permanent standard feature in Java 14.

Therefore code such as:

Java
String result = switch (value) {
    case 1 -> "One";
    default -> "Other";
};

should not be presented as Java 8-compatible syntax.

If your production project runs Java 8 or Java 11, this syntax is unavailable.

Always check the project's Java version.


55. Arrow Syntax#

Modern switch allows arrow labels:

Java
case value -> result

Example:

Java
public class ModernSwitchExample {
    public static void main(String[] args) {
        int day = 2;

        String dayName = switch (day) {
            case 1 -> "Monday";
            case 2 -> "Tuesday";
            case 3 -> "Wednesday";
            case 4 -> "Thursday";
            case 5 -> "Friday";
            case 6 -> "Saturday";
            case 7 -> "Sunday";
            default -> "Invalid";
        };

        System.out.println(dayName);
    }
}

Output:

Output
Tuesday

Notice the semicolon after the closing brace:

Java
};

Why?

Because the switch expression is part of this assignment:

Java
String dayName = ...;

The assignment statement must end with ;.


56. Arrow Syntax Avoids Traditional Fall-Through#

Consider:

Java
int value = 1;

switch (value) {
    case 1 -> System.out.println("One");
    case 2 -> System.out.println("Two");
    case 3 -> System.out.println("Three");
    default -> System.out.println("Other");
}

Output:

Output
One

Java does not continue into case 2 and case 3 in the traditional fall-through manner.

This makes many switch implementations safer and clearer.


57. Multiple Labels in Modern Switch#

Suppose Saturday and Sunday should both return "Weekend".

Modern syntax:

Java
int day = 6;

String type = switch (day) {
    case 1, 2, 3, 4, 5 -> "Weekday";
    case 6, 7 -> "Weekend";
    default -> "Invalid";
};

System.out.println(type);

Output:

Output
Weekend

This is cleaner than traditional intentional fall-through.


58. What If a Switch Expression Branch Needs Multiple Statements?#

Simple branch:

Java
case 1 -> "One"

But suppose a case needs:

  1. logging,
  2. calculation,
  3. then producing a value.

We cannot just place multiple statements after the arrow without a block.

We can use:

Java
case 1 -> {
    // statements
}

But now we need a way to return the branch's value to the switch expression.

That is where yield appears.


59. yield#

yield provides a value from a block inside a switch expression.

Example:

Java
public class YieldExample {
    public static void main(String[] args) {
        int score = 1;

        String result = switch (score) {
            case 1 -> {
                System.out.println("Processing case 1");
                yield "One";
            }

            case 2 -> {
                System.out.println("Processing case 2");
                yield "Two";
            }

            default -> {
                System.out.println("Processing default");
                yield "Unknown";
            }
        };

        System.out.println(result);
    }
}

Output:

Output
Processing case 1
One

Inside:

Java
case 1 -> {
    System.out.println("Processing case 1");
    yield "One";
}

yield "One"; means:

The value produced by this branch is "One".

60. yield Is Not the Same as return#

Suppose a switch expression is inside a method.

Java
public static String getDescription(int value) {
    return switch (value) {
        case 1 -> {
            System.out.println("Case 1");
            yield "One";
        }

        default -> "Other";
    };
}

Here:

Java
yield "One";

provides a value to the switch expression.

Then:

Java
return switch (...)

returns the final value from the method.

Mental model:

Output
yield
  ↓
gives value to switch expression
  ↓
switch expression evaluates
  ↓
return
  ↓
gives method result to caller

They operate at different levels.


61. break vs yield#

This is an excellent interview comparison.

Aspectbreakyield
Primary purposeTransfer control outProduce a switch-expression value
Traditional switchCommonNot used for this purpose
Switch expression blockDoes not provide required resultProvides result
Produces branch valueNoYes
Typical syntaxbreak;yield value;

Example traditional:

Java
switch (value) {
    case 1:
        System.out.println("One");
        break;
}

Example expression block:

Java
String result = switch (value) {
    case 1 -> {
        System.out.println("One");
        yield "ONE";
    }

    default -> "OTHER";
};

62. Switch Expression Must Produce a Value#

Consider:

Java
String result = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
};

There is a problem.

What should happen if:

Java
day = 99;

Because the switch expression must produce a result, its cases generally need to be exhaustive.

For simple integer cases, this usually means adding:

Java
default

Example:

Java
String result = switch (day) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    default -> "Unknown";
};

Enums can sometimes allow exhaustiveness without a default when every possible enum constant is covered, depending on the switch form and compiler analysis.

The core idea is:

If a switch is being used as an expression, Java must know that execution can produce a value on every reachable selector path.

63. Traditional Switch Statement vs Modern Switch Expression#

DimensionTraditional SwitchSwitch Expression
Typical syntaxcase X:often case X ->
Main roleControl flowCan produce value
Fall-throughPossible with colon formArrow rules avoid normal fall-through
breakOften neededNot used to produce branch value
yieldNot normally neededUsed for multi-statement value-producing block
AssignmentUsually assign inside casesSwitch itself can be assigned
BoilerplateOften moreUsually less
Java availabilityOlder Java versionsStandard from Java 14

Traditional#

Java
String type;

switch (day) {
    case 1:
        type = "Weekday";
        break;

    case 7:
        type = "Weekend";
        break;

    default:
        type = "Unknown";
}

Modern#

Java
String type = switch (day) {
    case 1 -> "Weekday";
    case 7 -> "Weekend";
    default -> "Unknown";
};

64. Arrow Labels Can Also Be Used Without Assignment#

Do not think -> automatically means:

This must be assigned somewhere.

Modern switch statement forms can also use arrow rules for side effects.

Java
int choice = 1;

switch (choice) {
    case 1 -> System.out.println("Create");
    case 2 -> System.out.println("Update");
    case 3 -> System.out.println("Delete");
    default -> System.out.println("Invalid");
}

There is no variable assignment here.

So distinguish:

Output
modern arrow switch rule

from:

Output
switch expression

A switch expression is specifically being used where a value is expected.


65. Grouping Cases — Traditional vs Modern#

Traditional#

Java
switch (day) {
    case 6:
    case 7:
        System.out.println("Weekend");
        break;

    default:
        System.out.println("Weekday");
}

Modern#

Java
switch (day) {
    case 6, 7 -> System.out.println("Weekend");
    default -> System.out.println("Weekday");
}

The modern form communicates intent more directly.


66. Another Decision Tool — Ternary Operator#

Now imagine a very small decision.

Output
If age >= 18
    status = "Adult"
else
    status = "Minor"

Writing this is perfectly valid:

Java
String status;

if (age >= 18) {
    status = "Adult";
} else {
    status = "Minor";
}

But for a simple value selection, Java gives us a compact conditional operator.

It is commonly called the ternary operator.


67. Ternary Operator#

Syntax:

Java
condition ? valueIfTrue : valueIfFalse

Example:

Java
int age = 20;

String status = age >= 18 ? "Adult" : "Minor";

System.out.println(status);

Output:

Output
Adult

Mental model:

Output
         age >= 18
            ↓
      ┌─────┴─────┐
    true         false
      ↓             ↓
 "Adult"         "Minor"
      └─────┬───────┘
            ↓
          status

68. Why Is It Called Ternary?#

“Ternary” means the operator works with three operands.

Java
condition ? value1 : value2

The three parts are:

Output
1. condition
2. value when true
3. value when false

69. Ternary Is an Expression#

This matters.

An if statement controls execution.

A ternary expression produces a value.

Example:

Java
int number = 10;

String type = number % 2 == 0 ? "Even" : "Odd";

The expression:

Java
number % 2 == 0 ? "Even" : "Odd"

evaluates to either "Even" or "Odd".


70. Ternary in a Method Call#

Because it is an expression, it can appear where a value is expected.

Java
int marks = 75;

System.out.println(marks >= 40 ? "Pass" : "Fail");

Output:

Output
Pass

This is valid, although readability should still guide usage.


71. Ternary for Numeric Values#

Java
int a = 10;
int b = 20;

int max = a > b ? a : b;

System.out.println(max);

Output:

Output
20

72. Ternary Should Not Replace Complex if Logic#

This is technically possible:

Java
String grade = marks >= 90
        ? "A"
        : marks >= 80
        ? "B"
        : marks >= 70
        ? "C"
        : "D";

But nested ternary expressions can quickly become difficult to read.

A clearer version may be:

Java
String grade;

if (marks >= 90) {
    grade = "A";
} else if (marks >= 80) {
    grade = "B";
} else if (marks >= 70) {
    grade = "C";
} else {
    grade = "D";
}

Or, depending on the exact problem and Java version, another approach may communicate the business rule better.

Practical Rule#

Use ternary for small, obvious value choices.

Do not use it merely to make code shorter.

Shorter code is not automatically better code.


73. Ternary and Side Effects#

Code such as this may compile:

Java
boolean success = true;

System.out.println(success ? "Saved" : "Failed");

Good.

But trying to pack complex side-effect-heavy behavior into ternary expressions usually harms readability.

Prefer normal control flow when branches perform several operations.


74. Choosing Between if and switch#

This is not a question of:

Which one is always better?

The answer depends on the shape of the decision.


75. Use if When Conditions Involve Ranges#

Example:

Java
if (age < 13) {
    System.out.println("Child");
} else if (age < 18) {
    System.out.println("Teenager");
} else {
    System.out.println("Adult");
}

This naturally uses relational conditions.

Traditional switch is not designed around arbitrary conditions like:

Java
age < 13

76. Use if for Complex Boolean Logic#

Example:

Java
if ((premium || admin) && active && !blocked) {
    System.out.println("Access granted");
}

This is a compound boolean rule.

if communicates it naturally.


77. Use switch for Discrete Value Selection#

Example:

Java
switch (command) {
    case "START":
        start();
        break;

    case "STOP":
        stop();
        break;

    case "PAUSE":
        pause();
        break;

    default:
        handleUnknownCommand();
}

You are testing one selector against a fixed set of discrete alternatives.

That fits switch well.


78. Use Modern Switch Expressions for Value Mapping#

Example:

Java
String label = switch (statusCode) {
    case 200 -> "Success";
    case 400 -> "Bad Request";
    case 404 -> "Not Found";
    case 500 -> "Server Error";
    default -> "Other";
};

This is clear because the switch maps:

Output
input value
    ↓
output value

79. Use Ternary for Very Small Two-Way Value Selection#

Example:

Java
String label = active ? "Active" : "Inactive";

This is clearer than:

Java
String label;

if (active) {
    label = "Active";
} else {
    label = "Inactive";
}

However, if each branch requires several statements, use if-else.


80. Decision Guide#

Output
Do you need a decision?
        ↓
        yes
        ↓
Is it a simple two-way value choice?
        │
        ├── yes → consider ternary
        │
        └── no
             ↓
Does decision depend on ranges,
different variables, or complex boolean logic?
        │
        ├── yes → if / else-if
        │
        └── no
             ↓
Are you matching one expression
against discrete constant-like values?
        │
        ├── yes → switch
        │
        └── no → if is usually clearer

81. Complete Comparison#

Featureifif-elseif-else-ifswitchTernary
Single conditionExcellentGoodPossibleUsually unnecessaryPossible
Two branchesPossibleExcellentPossiblePossibleExcellent for simple values
Many discrete valuesVerboseVerbosePossibleExcellentPoor
RangesExcellentExcellentExcellentUsually poor fitSimple only
Complex boolean logicExcellentExcellentExcellentLimited fitAvoid when complex
Produces value directlyNoNoNoModern switch canYes
Multiple statements per branchExcellentExcellentExcellentExcellentPoor readability
Fall-through concernNoNoNoTraditional syntax: yesNo

82. Common Mistakes#

Mistake 1 — Using = Instead of Intended Boolean Comparison#

Risky#

Java
boolean active = false;

if (active = true) {
    System.out.println("Active");
}

Why Developers Make It#

= and == look similar.

Consequence#

The program changes active to true, so the branch executes.

Preferred#

Java
if (active) {
    System.out.println("Active");
}

Debugging Clue#

A boolean unexpectedly changes before the branch.

Interview Connection#

Interviewers may ask whether assignment is allowed inside an if condition.

For boolean assignment expressions, yes, because the expression itself produces a boolean result—but it is usually unintended and poor style.


Mistake 2 — Wrong Boundary Operator#

Requirement:

Output
18 and above

Wrong:

Java
if (age > 18) {
    System.out.println("Eligible");
}

Correct:

Java
if (age >= 18) {
    System.out.println("Eligible");
}

Consequence:

Boundary value 18 behaves incorrectly.


Mistake 3 — Incorrect else-if Ordering#

Risky:

Java
if (marks >= 40) {
    System.out.println("Pass");
} else if (marks >= 75) {
    System.out.println("Distinction");
}

For 90, first condition already matches.

Preferred:

Java
if (marks >= 75) {
    System.out.println("Distinction");
} else if (marks >= 40) {
    System.out.println("Pass");
} else {
    System.out.println("Fail");
}

Mistake 4 — Using Independent ifs When Branches Must Be Exclusive#

Java
int marks = 95;

if (marks >= 40) {
    System.out.println("Pass");
}

if (marks >= 75) {
    System.out.println("Distinction");
}

This may be correct if both messages are intended.

It is wrong only if the business requirement demands exactly one classification.

Then use:

Java
if (marks >= 75) {
    System.out.println("Distinction");
} else if (marks >= 40) {
    System.out.println("Pass");
} else {
    System.out.println("Fail");
}

Mistake 5 — Missing Braces Creating Misleading Code#

Risky:

Java
if (admin)
    System.out.println("Admin");
    System.out.println("Sensitive action");

The second print is unconditional.

Preferred:

Java
if (admin) {
    System.out.println("Admin");
    System.out.println("Sensitive action");
}

Mistake 6 — Wrong Short-Circuit Order#

Dangerous:

Java
if (!name.isEmpty() && name != null) {
    System.out.println(name);
}

If name is null, the method call happens first.

Preferred:

Java
if (name != null && !name.isEmpty()) {
    System.out.println(name);
}

Mistake 7 — Accidentally Using & Instead of &&#

Java
if (name != null & !name.isEmpty()) {
    System.out.println(name);
}

Both operands are evaluated.

Therefore name.isEmpty() may still execute when name is null.

Preferred:

Java
if (name != null && !name.isEmpty()) {
    System.out.println(name);
}

Mistake 8 — Forgetting break in Traditional Switch#

Risky:

Java
switch (choice) {
    case 1:
        System.out.println("Create");

    case 2:
        System.out.println("Update");
}

For choice = 1, both messages execute.

Preferred when fall-through is not intentional:

Java
switch (choice) {
    case 1:
        System.out.println("Create");
        break;

    case 2:
        System.out.println("Update");
        break;
}

Or on a compatible modern Java version:

Java
switch (choice) {
    case 1 -> System.out.println("Create");
    case 2 -> System.out.println("Update");
    default -> System.out.println("Unknown");
}

Mistake 9 — Assuming default Handles Null#

Java
String role = null;

switch (role) {
    default:
        System.out.println("Unknown");
}

Traditional string switch does not simply route null to default.

Null may cause NullPointerException.

Validate appropriately.


Mistake 10 — Using Switch for Range Logic#

Hard-to-read workaround logic should not be forced into switch just because switch exists.

For ranges:

Java
if (score >= 90) {
    // ...
} else if (score >= 80) {
    // ...
}

is generally more natural.


Mistake 11 — Deeply Nested Conditions#

Risky for maintainability:

Java
if (user != null) {
    if (user.isActive()) {
        if (user.hasPermission()) {
            if (requestIsValid) {
                process();
            }
        }
    }
}

When appropriate, restructure the logic.

For example:

Java
if (user == null) {
    return;
}

if (!user.isActive()) {
    return;
}

if (!user.hasPermission()) {
    return;
}

if (!requestIsValid) {
    return;
}

process();

These early exits are often called guard clauses.

The exact approach depends on surrounding method semantics.


Mistake 12 — Nested Ternary Abuse#

Risky:

Java
String result = score >= 90 ? "A" : score >= 80 ? "B" : score >= 70 ? "C" : "D";

It may be syntactically valid but harder to scan and maintain.

Prefer an if-else-if structure when conditions become non-trivial.


83. Edge Cases and Traps#

Null Values#

Check nullable references before dereferencing them.

Java
if (name != null && !name.isEmpty()) {
    // safe to use name here
}

Empty Strings#

Null and empty are different.

Java
String a = null;
String b = "";

For b:

Java
b.isEmpty()

is valid and returns true.

For a:

Java
a.isEmpty()

throws NullPointerException.


Boundary Numbers#

Always test values:

Output
just below boundary
exactly boundary
just above boundary

For:

Java
age >= 18

test:

Output
17
18
19

Invalid Input#

Classification logic should not silently treat invalid input as valid.

Java
if (marks < 0 || marks > 100) {
    System.out.println("Invalid");
}

Duplicate Case Labels#

A switch cannot contain duplicate case labels for the same constant value.

This does not compile:

Java
switch (value) {
    case 1:
        System.out.println("A");
        break;

    case 1:
        System.out.println("B");
        break;
}

Traditional Fall-Through#

Always determine whether fall-through is intentional.

If intentional, make the structure obvious.

If not intentional, use break or modern arrow syntax where available.


84. Internal Working Mental Model#

At the language level, your most useful mental model is not JVM bytecode trivia.

Think in decision steps.

if#

Output
evaluate boolean condition
        ↓
true? ──yes──→ execute branch
  │
  no
  ↓
skip branch

if-else-if#

Output
condition 1
   │
 true → branch 1 → done
   │
 false
   ↓
condition 2
   │
 true → branch 2 → done
   │
 false
   ↓
...
   ↓
else

Traditional switch#

Output
evaluate selector once
        ↓
find matching case
        ↓
begin execution there
        ↓
continue sequentially
        ↓
break / end of switch

Arrow Switch#

Output
evaluate selector
       ↓
select matching rule
       ↓
execute only that rule

Switch Expression#

Output
evaluate selector
       ↓
select branch
       ↓
branch produces value
       ↓
switch expression has result
       ↓
result used by surrounding expression

85. Performance Perspective#

Developers sometimes ask:

Is switch faster than if?

That is usually the wrong starting point.

Compilers and the JVM can optimize control flow in different ways depending on selector type, value density, bytecode shape, runtime profiling, and other factors.

For normal business code, the primary decision should usually be:

Output
Which structure represents the requirement clearly and correctly?

Do not rewrite a readable three-branch if into a strange switch because of imagined nanosecond gains.

Performance optimization should be based on evidence and profiling when performance actually matters.


86. Production Perspective#

Decision-making code directly represents business rules.

That makes readability especially important.

Compare:

Java
if (a && b && !c && (d || e)) {
    process();
}

with:

Java
boolean eligibleCustomer = age >= 18 && accountActive;
boolean transactionAllowed = !blocked && (adminApproved || withinLimit);

if (eligibleCustomer && transactionAllowed) {
    process();
}

Depending on the context, meaningful intermediate variables may make the rule easier to review and test.

Production concerns include:

  • correct boundaries,
  • null handling,
  • invalid-state handling,
  • explicit business rules,
  • avoiding unintended fall-through,
  • readable condition names,
  • testable branches,
  • avoiding unnecessary nesting,
  • compatibility with the project's Java version.

87. Testing Decision Logic#

For every important conditional rule, test all meaningful paths.

Suppose:

Java
if (age >= 18 && verified) {
    allow();
} else {
    reject();
}

Meaningful test cases include:

AgeVerifiedExpected
17trueReject
18trueAllow
19trueAllow
18falseReject
17falseReject

The exact boundary value deserves special attention.


88. Real-World Example — E-Commerce Discount#

Requirement:

Output
Premium customer:
    20% discount

Regular customer spending at least 5000:
    10% discount

Others:
    no discount

Implementation:

Java
public class DiscountExample {
    public static void main(String[] args) {
        boolean premium = false;
        double orderAmount = 6000;

        double discountPercentage;

        if (premium) {
            discountPercentage = 20;
        } else if (orderAmount >= 5000) {
            discountPercentage = 10;
        } else {
            discountPercentage = 0;
        }

        double discountAmount = orderAmount * discountPercentage / 100;
        double finalAmount = orderAmount - discountAmount;

        System.out.println("Discount: " + discountPercentage + "%");
        System.out.println("Final amount: " + finalAmount);
    }
}

Output:

Output
Discount: 10.0%
Final amount: 5400.0

89. Real-World Example — Permission Check#

Java
public class PermissionExample {
    public static void main(String[] args) {
        boolean authenticated = true;
        boolean admin = false;
        boolean manager = true;
        boolean blocked = false;

        if (authenticated && !blocked && (admin || manager)) {
            System.out.println("Sensitive report access granted.");
        } else {
            System.out.println("Access denied.");
        }
    }
}

Output:

Output
Sensitive report access granted.

Read the condition in English:

Output
authenticated
AND
not blocked
AND
(admin OR manager)

Turning a boolean expression back into plain language is an excellent debugging technique.


90. Real-World Example — Order Status with Modern Switch#

Assume Java 14+.

Java
public class OrderStatusExample {
    public static void main(String[] args) {
        String status = "SHIPPED";

        String message = switch (status) {
            case "NEW" -> "Order received";
            case "PAID" -> "Payment completed";
            case "PACKED" -> "Order packed";
            case "SHIPPED" -> "Order is on the way";
            case "DELIVERED" -> "Order delivered";
            case "CANCELLED" -> "Order cancelled";
            default -> "Unknown order status";
        };

        System.out.println(message);
    }
}

Output:

Output
Order is on the way

This is a strong switch use case because one value is being mapped to one of several discrete results.


91. Real-World Example — Validation with Guard Clauses#

Java
public static void processWithdrawal(
        boolean authenticated,
        double amount,
        double balance) {

    if (!authenticated) {
        System.out.println("Authentication required.");
        return;
    }

    if (amount <= 0) {
        System.out.println("Amount must be positive.");
        return;
    }

    if (amount > balance) {
        System.out.println("Insufficient balance.");
        return;
    }

    System.out.println("Withdrawal approved.");
}

Why may this be easier than deep nesting?

Because each invalid situation is rejected early.

The happy path remains simple:

Java
System.out.println("Withdrawal approved.");

92. Revision — One-Line Definitions#

Control Flow: The order in which program statements execute.

if: Executes a block only when a boolean condition is true.

if-else: Chooses between two mutually exclusive branches.

if-else-if: Checks multiple conditions in order and executes the first matching branch.

Nested if: An if contained inside another conditional branch.

Multiple Conditions: Boolean expressions combined using logical operators such as &&, ||, and !.

switch: Selects a branch based on one selector value.

Traditional Switch: Colon-style switch where execution can fall through until a break or switch end.

Switch Expression: A switch form capable of producing a value.

Arrow Syntax: Modern case ... -> switch rule syntax.

yield: Produces a value from a block within a switch expression.

break: Transfers control out of the current switch in the context discussed here.

Fall-Through: Traditional switch behavior where execution continues into subsequent case bodies when not stopped.

Ternary Operator: Compact conditional expression: condition ? trueValue : falseValue.


93. Syntax Revision#

if#

Java
if (condition) {
    // statements
}

if-else#

Java
if (condition) {
    // true branch
} else {
    // false branch
}

if-else-if#

Java
if (condition1) {
    // branch 1
} else if (condition2) {
    // branch 2
} else {
    // fallback
}

Traditional Switch#

Java
switch (value) {
    case 1:
        // statements
        break;

    default:
        // fallback
}

Modern Switch Expression#

Java
String result = switch (value) {
    case 1 -> "One";
    case 2 -> "Two";
    default -> "Other";
};

yield#

Java
String result = switch (value) {
    case 1 -> {
        System.out.println("Processing");
        yield "One";
    }

    default -> "Other";
};

Ternary#

Java
String result = condition ? "Yes" : "No";

94. If You Remember Only 10 Things#

  1. Every Java if condition must evaluate to boolean.
  2. if-else selects exactly one of two branches.
  3. An if-else-if ladder stops at the first true branch.
  4. Order matters when conditions overlap.
  5. && and || short-circuit.
  6. Put prerequisite safety checks before expressions that depend on them.
  7. Traditional switch can fall through when break is missing.
  8. Modern arrow switch rules avoid ordinary traditional fall-through.
  9. A switch expression can produce a value; yield provides the value from a multi-statement block.
  10. Choose the control structure that best represents the business rule, not the one that merely produces the shortest code.

95. Final Knowledge Map#

Output
Decision Making and Control Flow
│
├── Foundation
│   ├── Sequential execution
│   ├── Control flow
│   ├── boolean
│   └── boolean expressions
│
├── if Family
│   ├── if
│   ├── if-else
│   ├── if-else-if
│   ├── ordering
│   ├── boundaries
│   └── nested if
│
├── Multiple Conditions
│   ├── &&
│   ├── ||
│   ├── !
│   ├── precedence
│   ├── parentheses
│   └── short-circuit evaluation
│
├── switch
│   ├── selector
│   ├── case
│   ├── default
│   ├── traditional switch
│   ├── break
│   └── fall-through
│
├── Modern Switch
│   ├── switch expression
│   ├── arrow syntax
│   ├── multiple labels
│   ├── exhaustive value production
│   └── yield
│
├── Conditional Expression
│   └── ternary operator
│
├── Decision Rules
│   ├── ranges → if
│   ├── complex boolean logic → if
│   ├── discrete selector values → switch
│   └── simple two-way value → ternary
│
├── Production Concerns
│   ├── boundaries
│   ├── null safety
│   ├── readability
│   ├── fall-through
│   ├── validation
│   ├── testing
│   └── Java-version compatibility
│
└── Interview
    ├── execution flow
    ├── short-circuiting
    ├── fall-through
    ├── break vs yield
    ├── switch statement vs expression
    └── if vs switch

Practice lab

Prove what you just learned