Skip to content
Study Hall
Lesson 3 of 3If Statements
Unit 3 · Lesson 3 of 3

switch, Validation and Choosing a Structure

The switch statement and its fall-through behaviour, when it beats an else if chain, and how to validate input so bad data never reaches your calculation.

6 min read12 practice questionsAsk AI about this →

Key things to remember

  1. 1switch compares one selector against fixed case constants; default handles everything unmatched.
  2. 2break exits the switch. Without it, execution falls through into the statements of the cases below.
  3. 3Stacked bare labels such as case 4: case 6: are deliberate fall-through and share one block.
  4. 4A switch selector may be int, short, byte, char, String or an enum — never double, float, long or boolean.
  5. 5Use switch for a list of fixed values and else if for ranges, decimals or multi-variable conditions.
  6. 6Integer division by zero throws ArithmeticException; double division by zero gives Infinity or NaN silently.

When a decision compares one variable against a list of specific fixed values, an else if chain repeats that variable on every line. The switch statement says it once and then lists the cases underneath. It is not more powerful than an if chain — anything a switch does can be written with else if — but for the right shape of problem it is far easier to read and far harder to get wrong.

A switch jumps straight to the matching case, then keeps running until a break.switch (day) { case 1: case 2: type = "start"; break; case 3: type = "mid"; break; default: type = "other";}falls throughfall-throughcase 1 has no body and nobreak, so day 1 slides intocase 2 — both give "start".breakbreak jumps out of the wholeswitch, straight past everycase below it.defaultdefault runs only when nocase matched. Leave it outand an unmatched value doesnothing at all.the classic bugA missing break falls intothe next case by accident.switch tests one value for exact equality against constants — anything with a range still needs if / else if.
Fig 1The parts of a switch: the selector, the case labels, the breaks, and the default.
int month = 4;
int days;

switch (month) {
    case 1: case 3: case 5: case 7: case 8: case 10: case 12:
        days = 31;
        break;
    case 4: case 6: case 9: case 11:
        days = 30;
        break;
    case 2:
        days = 28;
        break;
    default:
        days = 0;   // not a real month
}

System.out.println(days);   // prints 30
Stacked case labels are deliberate fall-through: 4, 6, 9 and 11 all reach the same statements.

The value in the brackets is the selector, and Java jumps to the case label whose constant matches it. Execution then continues from that point until it meets a break, which exits the whole switch. default catches every value that matched no case, and it plays the same role as the final else in a chain. Case labels must be compile-time constants, not variables or ranges, which is the main limit on where a switch can be used.

Selector typeAllowed in a switch?Note
int, short, byte, charYesThe everyday cases — menu choices, month numbers, letter grades
StringYesCompares by content, like .equals(), so no == trap here
enumYesThe neatest fit of all, since the cases are named constants already
double, floatNoExact equality on decimals is unreliable, so Java forbids it
long, booleanNoA boolean has only two values, which is what if / else is for
A switch tests one value against fixed constants, so ranges and decimals are out of reach.
int code = 2;

switch (code) {
    case 1:
        System.out.println("One");
    case 2:
        System.out.println("Two");
    case 3:
        System.out.println("Three");
    default:
        System.out.println("Other");
}
// prints: Two, then Three, then Other — every break is missing
Accidental fall-through. Execution enters at case 2 and runs on through everything below.
A missing break does not stop the switch
A case label is an entry point, not a container. Once execution enters, it continues through every statement below it, including the statements of later cases, until a break or the closing brace. Stacking bare labels with nothing between them is a legitimate way to group cases, but a missing break after real statements is a bug that compiles silently.

Choosing between switch and else if

AUse a switch when
  • One variable is compared against several fixed, known values
  • The values are whole numbers, characters or Strings
  • A menu, a month number, a letter grade or a command word
  • You want every option visible in one flat, readable list
BUse else if when
  • The tests are ranges, such as mark >= 80
  • The selector is a double, or the tests involve more than one variable
  • Conditions combine with && or ||
  • Each branch asks a genuinely different question

Validating input

Every value that comes from outside your program is a guess until you check it. A user types a letter where a number was expected, enters a negative age, or leaves a count at zero and then your program divides by it. Validation means testing an input against what your calculation actually requires, before the calculation runs, and having a plan for the case where it fails.

import java.util.Scanner;

public class Marks {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter a mark out of 100: ");

        if (!sc.hasNextInt()) {                 // is the next token even a number?
            System.out.println("That is not a whole number.");
        } else {
            int mark = sc.nextInt();
            if (mark < 0 || mark > 100) {       // range check
                System.out.println("A mark must be from 0 to 100.");
            } else {
                System.out.println("Accepted: " + mark);
            }
        }
    }
}
Check the type first with hasNextInt, then the range. Reading first would already have crashed.
Guard every division
Dividing an int by zero throws ArithmeticException and stops the program. Dividing a double by zero does not crash at all — it quietly produces Infinity, or NaN when zero is divided by zero, and that value then poisons every calculation downstream. Neither outcome is acceptable, so test the divisor before you use it.
int total = 0;
int count = 0;

if (count == 0) {
    System.out.println("No marks entered, so there is no average.");
} else {
    double average = (double) total / count;
    System.out.println("Average: " + average);
}

System.out.println(5.0 / 0);     // Infinity — no exception, no warning
System.out.println(0.0 / 0.0);   // NaN
The int division is guarded; the two double divisions show why silence is the greater danger.
Tracing by hand is how you find a logic error the computer will not report.total = 0i = 1while i <= 4: total = total + i i = i + 1itotalpasscondition—00—1111 ≤ 4 true2322 ≤ 4 true3633 ≤ 4 true41044 ≤ 4 true51055 ≤ 4 FALSE — exitFinal total = 10One row per pass.Write down everyvariable, every time.Forget the i = i + 1 line andthe table never ends: infinite loop.
Fig 2A trace table records each variable after every line, which is how you check a decision by hand.
  • Validate as early as possible, at the moment the value is read, so bad data never travels.
  • Test the type first (hasNextInt), then the range, then any rule specific to your problem.
  • Say what is wrong and what would be acceptable: a mark must be from 0 to 100 beats invalid input.
  • Guard every divisor, every index and every value that could be zero, negative or missing.
  • Check boundaries deliberately: for a 0 to 100 range, test −1, 0, 100 and 101, not just 50.

Worked examples

Reveal one step at a time and try to beat it to the next line.

Example 1
State the exact output when code is 2 in a switch whose cases 1, 2, 3 and default all lack a break.
Example 2
A program must print the name of the season for a month number. Decide whether to use a switch or an else if chain, then write it.
Example 3
A marks program reads a count and a total, then prints total / count. Describe every validation it needs and write the guard.

Where marks get lost

  • Forgetting break, so a matched case runs on into every case below it and prints several answers.
  • Trying to switch on a range, such as case mark >= 80:. Case labels must be single constant values.
  • Switching on a double, which Java rejects because exact equality on decimals cannot be trusted.
  • Leaving out default, so an unexpected value silently does nothing at all and the bug stays hidden.
  • Reading a number with nextInt() before checking hasNextInt(), so bad input crashes instead of being reported.

Flashcards 10

What does break do inside a switch?
What is fall-through?
What does default do?
Which types can a switch selector be?
+ 6 more

Practice

1
What happens when a matched case has no break at the end of its statements?
2
Which of these cannot be used as the selector in a switch?
3
In a switch with cases 1, 2, 3 and default, all printing their own word and none having a break, what is printed when the selector is 3?
4
Using the days-in-month switch, what value is stored in days when month is 9?
5
What is the role of default in a switch?
6
Which problem is a better fit for an else if chain than for a switch?
7
What does int result = 7 / 0; do when the program runs?
8
What does System.out.println(5.0 / 0); print?
9
Order the checks a program should make before dividing a total by a user-supplied count.
  1. 1Perform the division
  2. 2Check that the count is not zero
  3. 3Check that the count is not negative
  4. 4Check that the typed token is actually a whole number with hasNextInt
  5. 5Read the value with nextInt
10
Match each part of a switch statement to its job.
selector
case
break
default
11
int n = 5; int r = 0; switch (n) { case 5: r += 1; case 6: r += 10; break; case 7: r += 100; } What is r?
12
Why should a validation message say what would be acceptable, not just that something is wrong?

Spot a mistake on this page? Let us know