Switch Expressions & Statements practice questions

From OCP Java SE 21 (1Z0-830) · 20 questions on this topic

Switch Expressions & Statements practice questions from OCP Java SE 21 (1Z0-830). This pack has 20 questions tagged Switch Expressions & Statements, drawn from its timed mock exams. 8 of them are worked through in full below — the question, every option, why each is right or wrong, and the explanation.

Worked examples for Switch Expressions & Statements

  1. Question 1

    What is the output of the following program? ```java public class Main { public static void main(String[] args) { int x = 1; switch (x) { case 1 -> System.out.println("alpha"); case 2 -> System.out.println("beta"); default -> System.out.println("gamma"); } } } ```

    1. A. alphaCorrect answer

      Arrow-case labels carry an implicit no-fall-through guarantee. Only case 1 matches x == 1; its body executes and control exits the switch statement immediately — no subsequent arm is reached (JEP 361).

    2. B. alpha beta

      Assumes arrow labels fall through like traditional colon-label cases. With arrow labels, fall-through never occurs — only the matched arm executes, and no break statement is required or relevant.

    3. C. alpha beta gamma

      Assumes all arms execute for every selector value. A switch evaluates exactly the matched arm and exits the construct; the default arm executes only when no case label matches, not unconditionally.

    4. D. Compilation fails

      Arrow labels were standardised by JEP 361 (finalised in Java 14) and are valid in switch statements as well as switch expressions. The code is syntactically and semantically correct under Java 21.

    Explanation

    Arrow-case labels (the -> form) never fall through: exactly the matched arm executes, and control immediately exits the switch construct without any break statement (JEP 361). This is the fundamental behavioural difference from traditional colon-label cases, which fall through to successive arms unless explicitly broken. A switch evaluates only the matched arm; unmatched arms — including default when another case matches — are skipped entirely. Expecting multiple consecutive arms to fire conflates the two switch syntaxes. Arrow labels are valid in both switch statements and switch expressions since Java 14, so the code compiles cleanly.

  2. Question 2

    This switch expression is written with colon labels. Only some of the groups end with yield. What does the program print? ```java public class Main { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); int n = 2; int r = switch (n) { case 1: sb.append("a"); case 2: sb.append("b"); case 3: sb.append("c"); yield 30; default: yield 0; }; System.out.println(sb + " " + r); } } ```

    1. A. Compilation fails: the group labelled `case 2` does not yield a value

      Assumes every group of a colon-form switch expression must end with its own yield. The real rule is weaker: the switch must not complete normally, which fall-through into a later `yield` satisfies — only the LAST group must not fall off the end.

    2. B. b 0

      Assumes the colon form behaves like the arrow form (case 2 ends at the next label) and then reaches for the default group. Colon groups fall through, and default runs only when no label matched, so control falls into case 3's yield 30.

    3. C. abc 30

      Assumes a colon switch begins at the first group and falls through all of them. Execution begins at the group whose label MATCHES the selector (case 2), so case 1 is skipped and only "bc" is appended.

    4. D. bc 30Correct answer

      The colon form keeps fall-through: n=2 enters case 2 (appends b), falls into case 3 (appends c) and executes yield 30, which completes the switch; case 1 and default are never reached, giving bc 30.

    Explanation

    Trace: the colon form of a switch expression keeps the classic fall-through semantics — only the arrow form abolishes them. `n` is 2, so control enters at `case 2`, appends `b`, and, with no `break` and no `yield` to stop it, falls straight through into the `case 3` group, which appends `c` and then executes `yield 30`. That `yield` is what completes the switch expression, so `r` is 30 and the builder holds `bc`. The `case 1` group is never entered (fall-through goes downwards from the matched label, never upwards) and the `default` group is never reached. Output: `bc 30`. Why the others are wrong: `b 0` assumes the colon form behaves like the arrow form — the `case 2` group ends at the next label — and then reaches for the `default` group to supply the missing value. Neither half is true: colon groups fall through, and `default` runs only when no label matched. `abc 30` assumes a colon switch begins executing at the first group and falls through all of them. Execution begins at the group whose label MATCHES the selector; earlier groups are skipped entirely. `Compilation fails: the group labelled `case 2`...` encodes the belief that every group of a colon-form switch expression must end with its own `yield`. The real rule is weaker: the switch expression must not be able to complete normally, which fall-through into a later `yield` satisfies. Only the LAST group must not fall off the end. Exam tip: a colon switch expression is a switch statement's body that happens to produce a value — fall-through is alive, and one `yield` can serve several labels. The reverse trap is mixing forms: a single switch may not use both `case x ->` and `case x:` arms, and that does fail to compile.

  3. Question 3

    What is the output of the following program? ```java public class Main { public static void main(String[] args) { int x = 1; switch (x) { case 1: System.out.print("A"); case 2: System.out.print("B"); break; case 3: System.out.print("C"); } } } ```

    1. A. A

      Assumes the switch statement stops after the matching case even without an explicit break. In a traditional switch statement, execution falls through to the next statement group unless stopped by break, return, or throw (JLS §14.11.1).

    2. B. ABC

      Assumes fall-through continues past the break in case 2. A break terminates the switch immediately, jumping to the first statement after the closing brace; case 3 is therefore never reached.

    3. C. Compilation fails

      The code is syntactically valid. A traditional switch statement does not require a break in every case; omitting it is legal Java that enables fall-through, not a compile error.

    4. D. ABCorrect answer

      x == 1 matches case 1, which prints "A". Because case 1 has no break, execution falls through into case 2, which prints "B" and then hits break, exiting the switch. Case 3 is never entered (JLS §14.11.1).

    Explanation

    In a traditional switch statement, when a case label matches, execution continues sequentially through all subsequent statements — including those belonging to later case groups — until a break, return, or throw is encountered, or the switch block ends (JLS §14.11.1). This is called fall-through. Here x equals 1, so case 1 is entered and prints "A"; the absence of break causes execution to fall into case 2, which prints "B" and then exits via break. Assuming every case ends with an implicit break produces only the first letter; ignoring the explicit break in case 2 produces all three letters.

  4. Question 4

    The loop variable is incremented inside the while condition itself. What does the program print? ```java public class Main { public static void main(String[] args) { int i = 0; int count = 0; while (i++ < 3) { count += i; } System.out.println(i + ":" + count); } } ```

    1. A. 3:3

      Reads i++ < 3 as if it were ++i < 3. Postfix compares the value before the increment, so the test succeeding at i == 2 still runs the body, and i ends at 4.

    2. B. 4:3

      Gets the exit value right but assumes the body sees the pre-increment value of i. The increment is complete before the body starts, so the body reads 1, 2, 3, summing to 6.

    3. C. 4:6Correct answer

      Each test compares the old i then increments; the body adds 1, 2, 3 (sum 6), and the failing fourth test still runs its increment, leaving i at 4.

    4. D. 3:6

      Gets the body sum right but assumes the failing test leaves i alone. The condition is fully evaluated every time, so the last increment runs even though the comparison is false, leaving i at 4.

    Explanation

    Trace: each test compares the OLD value of `i` and then increments. Test 1: 0 < 3 holds, `i` becomes 1, body adds 1 (count 1). Test 2: 1 < 3 holds, `i` becomes 2, body adds 2 (count 3). Test 3: 2 < 3 holds, `i` becomes 3, body adds 3 (count 6). Test 4: 3 < 3 is false — but the increment in the condition has ALREADY run, so `i` is 4 when the loop exits. Output: `4:6`. Why the others are wrong: `3:6` gets the body right but assumes the final, failing test leaves `i` alone. The condition is evaluated in full every time, so the increment on the last test happens even though the comparison is false — that trailing increment is the whole point of this idiom. `3:3` reads `i++ < 3` as if it were `++i < 3`: the body would then see 1, 2 and exit at `i == 3` with count 1 + 2 = 3. Postfix compares the value BEFORE the increment, so the test that succeeds at `i == 2` still runs the body. `4:3` gets the exit value right but assumes the body sees the pre-increment value of `i` (0, 1, 2 → count 3). The increment is complete by the time the body starts; the body reads the variable, not the value the condition produced. Exam tip: with `while (i++ < cond)`, the loop runs while the OLD value satisfies the test, and `i` ends one past the first value that fails it. Substitute `++i` and both numbers change — always separate "the value the expression yields" from "the value now in the variable".

  5. Question 5

    What is the output? ```java public class Main { public static void main(String[] args) { int sum = 0; outer: for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { if (j == 2) continue outer; if (i == 2) break outer; sum += 1; } } System.out.println(sum); } } ```

    1. A. 4Correct answer

      The i=0 and i=1 passes each add 2 before `continue outer`, and the i=2 pass hits `break outer` before any increment, leaving sum=4.

    2. B. 6

      6 treats the labeled `break` as if it were a labeled `continue`, wrongly letting the i=2 pass add two more.

    3. C. 5

      5 assumes `sum += 1` runs before the `i == 2` check on the last pass, but the `break outer` fires first.

    4. D. 9

      9 ignores both labeled jumps and simply counts all nine inner iterations.

    Explanation

    A labeled `continue` jumps to the update of the named outer loop, while a labeled `break` abandons that loop entirely. Tracing pass by pass, the first two outer passes each contribute two increments before continuing, and the third pass breaks out before any increment runs. The two jumps are easy to conflate, so the total settles at 4.

  6. Question 6

    What does this print? ```java public class Main { public static void main(String[] args) { int n = 3; String s = switch (n) { case 1, 2 -> "low"; case 3, 4 -> "mid"; default -> "high"; }; System.out.println(s); } } ```

    1. A. high

      "high" comes from `default`, which is chosen only when no label list contains the selector value; here the selector is matched by an explicit arm.

    2. B. Compilation fails: missing break

      Arrow arms need no `break`; there is nothing to fall through, so this is never a compile error in arrow form.

    3. C. low

      "low" is the `case 1, 2` arm; the selector 3 is not in that list.

    4. D. midCorrect answer

      The selector 3 matches the `case 3, 4` label list, so that arm yields "mid" and nothing else runs.

    Explanation

    Multiple constants on one arm form a single label rather than fall-through, so a selector value handled by that list selects its arm. Arrow arms evaluate only their own body with no fall-through, so the `default` arm is reached only when no label list contains the value. This differs from the old colon form, where reaching the next group required omitting `break`.

  7. Question 7

    A colon-form switch statement sits inside a labelled loop and one of its arms breaks the label. What does the program write to standard output? ```java public class Main { public static void main(String[] args) { StringBuilder sb = new StringBuilder(); outer: for (int i = 1; i <= 3; i++) { switch (i) { case 1: sb.append("a"); case 2: sb.append("b"); break; case 3: sb.append("c"); break outer; default: sb.append("d"); } sb.append(i); } System.out.println(sb); } } ```

    1. A. a1b2c

      Assumes the first case breaks implicitly; colon labels fall through, so the first iteration appends "a" then "b" before the break, and the index is appended after the switch.

    2. B. ab1b2c3

      Treats the labelled break as an ordinary switch break; it instead terminates the labelled loop, so the trailing "3" after the switch is never appended.

    3. C. ab1b2cCorrect answer

      The first iteration falls through into the next group ("ab") then breaks and appends "1"; the second gives "b2"; the third appends "c" and the labelled break ends the loop before "3".

    4. D. Compilation fails

      A labelled break targeting an enclosing labelled statement from inside a switch is legal, so it compiles.

    Explanation

    A colon-form switch group has no implicit break, so execution falls through into following groups until a break is reached, after which control resumes at the statement following the switch. A labelled break, however, targets the named enclosing statement itself, so it exits that loop entirely rather than merely leaving the switch, skipping any code that would otherwise run after the switch.

  8. Question 8

    What is the output of the following program? ```java public class Main { public static void main(String[] args) { int n = 2; int result = switch (n) { case 1 -> 100; case 2 -> { System.out.print("computing "); yield n * n + 1; } default -> -1; }; System.out.println(result); } } ```

    1. A. 5

      Overlooks the System.out.print side effect. Statements inside a block arm execute in order before the yield hands a value back to the enclosing expression; the print fires and is already on stdout before result is assigned.

    2. B. computing 5Correct answer

      n=2 matches case 2. The block arm executes System.out.print("computing ") first, then evaluates and yields `n*n+1` = `2*2+1` = 5. After the switch expression completes, System.out.println(5) appends "5" and a newline, producing "computing 5".

    3. C. computing 6

      Misreads n * n + 1 as n * (n + 1). Java's standard arithmetic precedence makes * bind tighter than +, so the expression is (n * n) + 1 = 4 + 1 = 5, not 2 * (2 + 1) = 6.

    4. D. Compilation fails

      yield is precisely the mechanism JEP 361 introduced for producing a value from a block-style arrow arm. The compiler accepts it; the code is well-formed Java 21.

    Explanation

    A switch expression whose arrow arm is a block must supply its value with a yield statement (JEP 361, JLS §14.22). Unlike a bare-expression arm, a block arm can contain arbitrary statements before the yield — including I/O, local variable declarations, or loops — and those statements execute in order. yield exits the switch expression and hands back the specified value; it does not return from the enclosing method, so any code after the switch assignment continues to run. Here the print executes as a side effect inside the block, yield provides the integer value to complete the switch expression, and println appends that integer to the already-printed prefix.

Practise all 20 Switch Expressions & Statements questions

OCP Java SE 21 has the full set, inside timed mock exams that mirror real exam conditions — every question with a worked explanation.

Open OCP Java SE 21

Other topics in this pack