Switch Expressions & Statements practice questions

From OCP Java SE 17 (1Z0-829) · 19 questions on this topic

Switch Expressions & Statements practice questions from OCP Java SE 17 (1Z0-829). This pack has 19 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 does this print? ```java public class Main { public static void main(String[] args) { int i = 0; do { System.out.print(i); i++; } while (i < 3); } } ```

    1. A. 0123

      Needs a fourth pass, but the condition fails once the counter reaches 3, so 3 is never printed.

    2. B. 012Correct answer

      The body prints the current value then increments on each pass; after printing 2 the counter becomes 3, and 3 < 3 is false, ending the loop. (JLS §14.13)

    3. C. (no output)

      A do-while body always executes at least once, so the output is never empty.

    4. D. 123

      Would require incrementing before printing, but the body prints first and then increments.

    Explanation

    The do-while loop evaluates its condition after each pass, so the body runs — printing the current value and then incrementing — before the test decides whether to repeat. Starting from zero it prints 0, 1, 2, and after the value becomes 3 the condition fails and the loop stops. The output is 012. (JLS 17 §14.13 — the do statement)

  2. Question 2

    The loop condition below both tests and mutates the counter. What is written to standard output? ```java public class Main { public static void main(String[] args) { int i = 0; int total = 0; while (i++ < 3) { total += i; } System.out.println(i + " " + total); } } ```

    1. A. 4 6Correct answer

      Correct — postfix i++ tests the old value (the body sees 1, 2, 3, summing to 6) and increments each time, including the final failing test 3 < 3, leaving i at 4 (JLS 17 §15.14.2).

    2. B. 3 6

      Forgets that the final, failing comparison still increments i; postfix ++ runs on every evaluation, so i ends at 4, not 3.

    3. C. 3 3

      Assumes the body sees the pre-increment values 0, 1, 2; the postfix operator increments before the body runs, so the body sees 1, 2, 3 (total 6) and i ends at 4.

    4. D. 4 10

      Miscomputes the total; the body adds 1 + 2 + 3 = 6, not 10.

    Explanation

    The postfix i++ yields the OLD value for the comparison and increments i as a side effect (JLS 15.14.2), so the body sees i as 1, 2, 3 and total becomes 6; crucially the final, failing test (3 < 3) still increments i, leaving it at 4. '3 6' is the classic near-miss: it forgets that the increment happens on the failing evaluation too. '3 3' assumes the body sees the pre-increment values 0, 1, 2.

  3. Question 3

    Which two statements about switch expressions in Java 17 are correct? (Choose two.)

    1. A. A switch expression over an enum that lists every constant is exhaustive and needs no default clauseCorrect answer

      Exhaustiveness for an enum selector is satisfied by covering every constant; the compiler even inserts an implicit throwing default to guard against constants added after compilation.

    2. B. An arrow (->) arm never falls through into the next case, whether the switch is a statement or an expressionCorrect answer

      No-fall-through is a property of the arrow syntax itself, so it holds in statements and expressions alike; each arrow arm executes exactly one body.

    3. C. A block-bodied arm of a switch expression may complete normally without yielding a value

      Every completing path of a block arm must yield a value or throw; falling off the end of the block is a compile-time error.

    4. D. The value of an arm is produced with the syntax `break value;`

      `break value;` was the preview syntax dropped before standardization; final Java 14+ uses `yield value;`, and break cannot carry a value.

    Explanation

    Exhaustiveness for an enum switch expression is met by covering every constant, so no default clause is required, and the arrow form's no-fall-through behavior comes from the syntax itself and therefore applies to both switch statements and switch expressions. A block-bodied arm must yield a value or throw on every completing path, and the value-carrying keyword is `yield` — the preview break-with-value syntax was removed before standardization. (JLS 17 §15.28, JEP 361)

  4. Question 4

    What does this print? ```java public class Main { public static void main(String[] args) { int n = 1; switch (n) { case 1 -> System.out.print("one "); case 2 -> System.out.print("two "); default -> System.out.print("other "); } System.out.print("done"); } } ```

    1. A. one doneCorrect answer

      The selector 1 runs only its matching arrow arm, printing "one "; arrow arms never fall through, so control leaves the switch and the following statement prints "done".

    2. B. one two other done

      Full fall-through happens only in colon-form switches with no break; an arrow arm executes exactly one body.

    3. C. Compilation fails: arrow labels are not allowed in a switch statement

      Arrow labels are legal in both switch statements and switch expressions since Java 14, so this compiles.

    4. D. one two done

      Assumes partial fall-through, but arrow arms do not fall through at all; only one arm executes.

    Explanation

    Arrow labels never fall through, and that is a property of the arrow syntax itself, so it holds in a plain switch statement just as in a switch expression. With a selector of 1, only the matching arm executes and control then leaves the switch, so no break is needed. The result is the matched arm's output followed by the statement after the switch. (JLS 17 §14.11 — arrow labels do not fall through)

  5. Question 5

    A developer refactors a switch expression and leaves one arm in the old colon form. What is the result of compiling and running this program? ```java public class Main { static int score(int n) { return switch (n) { case 1 -> 10; case 2: yield 20; default -> 0; }; } public static void main(String[] args) { System.out.println(score(2)); } } ```

    1. A. 10

      Reads only the first arrow arm; the switch never compiles because it mixes arrow and colon labels, so no value is produced.

    2. B. Compilation failsCorrect answer

      Correct — a switch block must use one label kind throughout, and mixing a colon label among arrow arms is rejected with 'different case kinds used in the switch' (JLS 17 §14.11.1).

    3. C. 20

      Evaluates the colon arm in isolation; although a colon arm using yield is individually legal, mixing it with arrow arms is a compile error, so 20 is never returned.

    4. D. 0

      Assumes the default arm is reached at run time; the mixed label kinds prevent compilation, so nothing runs.

    Explanation

    A single switch block must use ONE case kind throughout: either all arrow labels (case L -> ...) or all colon labels (case L: ...). Mixing them, as `case 2: yield 20;` does here among arrow arms, is rejected with "different case kinds used in the switch" (JLS 17 §14.11.1). The trap is that each arm is individually legal — a colon arm may indeed use yield to produce a value in a switch EXPRESSION — so a candidate who checks the arms one at a time computes 20 and never notices the mixture.

  6. Question 6

    This arrow-form switch is used as a STATEMENT, it has no `default`, and no label matches the selector. What is written to standard output? ```java public class Main { public static void main(String[] args) { int code = 5; StringBuilder sb = new StringBuilder("["); switch (code) { case 1 -> sb.append("one"); case 2 -> sb.append("two"); } sb.append("]"); System.out.println(sb); } } ```

    1. A. The program throws an exception at runtime because no label matches

      Wrong: this imagines a MatchException-style throw. An unmatched selector in a switch statement is simply a no-op; nothing is thrown.

    2. B. []Correct answer

      Correct: a switch statement need not be exhaustive, so with no matching label and no default the switch does nothing. The buffer still holds only [ before ] is appended, giving [].

    3. C. [two]

      Wrong: this assumes an unmatched selector falls into the last arm. Arrow arms select exactly one arm by label; when none matches and there is no default, none is selected - there is no last-arm fallback.

    4. D. Compilation fails: the switch does not cover the value 5 and has no `default`

      Wrong: this applies the switch-expression exhaustiveness rule to a switch statement. Only a switch expression must be exhaustive; this statement compiles cleanly.

    Explanation

    Trace: exhaustiveness is a rule about switch EXPRESSIONS, not switch statements. A switch expression must produce a value, so every possible selector must be covered. A switch statement produces nothing, so an unmatched selector is legal and simply means no arm runs. `code` is 5, neither `case 1` nor `case 2` matches, there is no `default`, so the switch does nothing at all. The buffer still holds only `[`, then `]` is appended, and `[]` is printed. Why the others are wrong: `Compilation fails: the switch does not cover the value 5...` applies the switch-expression exhaustiveness rule to a switch statement. Only a switch expression (and, in Java 17, only over an enum can it be exhaustive without `default`) is required to be exhaustive. This program compiles cleanly. `[two]` assumes an unmatched selector falls into the last arm. Arrow arms select exactly one arm by label; when none matches and there is no `default`, none is selected — there is no "nearest" or "last" fallback. `The program throws an exception at runtime...` imagines something like the `MatchException` an exhaustive pattern switch can throw. Nothing is thrown here; the statement is a no-op. Exam tip: switch statement -> may be non-exhaustive, silently does nothing. Switch expression -> must be exhaustive, or it does not compile. The reverse trap: adding a `default` to a switch expression over an enum silences the compiler's helpful "you forgot a constant" error when someone later adds a constant to the enum.

  7. Question 7

    What is the result? ```java public class Main { public static void main(String[] args) { int n = 2; int r = switch (n) { case 1 -> 10; case 2 -> { int t = 20; yield t + 5; } default -> 0; }; System.out.println(r); } } ```

    1. A. 25Correct answer

      The selector 2 enters the block-bodied arm, which sets a local to 20 and yields that local plus 5, so the switch expression evaluates to 25. (JEP 361, yield)

    2. B. 20

      Uses only the intermediate local and ignores the `+ 5` inside the yield expression.

    3. C. Compilation fails: yield not allowed

      Inverts the rule: `yield` is required, not forbidden, to supply the value of a block-bodied arm of a switch expression.

    4. D. 0

      0 is the default arm's value, reached only when no case matches; the arm for 2 matches first.

    Explanation

    Block-bodied arms of a switch expression produce their value with `yield`, and the yielded expression is evaluated in full. With a selector of 2, the matching block computes an intermediate local and yields that value plus five, so the expression evaluates to 25. The default arm is never reached because an earlier label matches. (JEP 361 — Switch Expressions)

  8. Question 8

    The reference handed to this switch expression is null, and the switch has a `default` arm. What is written to standard output? ```java public class Main { static int size(String s) { return switch (s) { case "small" -> 1; case "large" -> 3; default -> 0; }; } public static void main(String[] args) { String s = null; try { System.out.println(size(s)); } catch (Exception e) { System.out.println(e.getClass().getSimpleName()); } } } ```

    1. A. Compilation fails: a switch over `String` may not be given a null selector

      Assumes the compiler rejects a possibly-null selector; nullability is not part of a type, so this is purely a run-time failure, not a compile error.

    2. B. NullPointerExceptionCorrect answer

      A switch on a String dereferences the selector (calling hashCode) before examining any label, so size(null) throws NullPointerException, which catch(Exception) catches and prints.

    3. C. 0

      Assumes default is a catch-all that also covers null; default matches only an actual value no case matched, and null never gets that far (Java 17 has no case null).

    4. D. Nothing is printed; the exception escapes `main` because `catch (Exception e)` does not catch unchecked exceptions

      Assumes catch(Exception) catches only checked exceptions; it catches every Exception including the unchecked NullPointerException, so it is caught and its name printed.

    Explanation

    Trace: a switch on a `String` (or a boxed type, or an enum) dereferences the selector before it looks at any label — for `String` the compiled switch calls `hashCode()` on it. So `size(null)` throws a NullPointerException the moment the switch is entered, before `"small"`, `"large"` or `default` are ever considered. `NullPointerException` extends `RuntimeException` extends `Exception`, so `catch (Exception e)` does catch it, and `e.getClass().getSimpleName()` prints `NullPointerException`. Why the others are wrong: `0` encodes the most common misconception here — that `default` is a catch-all that also covers null. It is not: `default` matches an actual selector value that no `case` label matched, and null never gets that far. (Java 21's `case null` label exists precisely because this hole was painful; it is not available in Java 17.) `Compilation fails: a switch over `String` may not be given...` assumes the compiler rejects a possibly-null selector. Nullability is not part of a type in Java, so the compiler cannot see it; this is purely a runtime failure. `Nothing is printed; the exception escapes `main`...` encodes the belief that `catch (Exception e)` only catches checked exceptions. It catches every `Exception`, checked or unchecked; only `Error` and other non-`Exception` `Throwable`s slip past. Exam tip: switch throws NullPointerException on a null selector, `default` or not. The reverse trap: `if`/`else if` chains and `equals("literal")` calls on a constant receiver are null-safe, which is why the switch rewrite of a null-tolerant if-chain is a classic bug.

Practise all 19 Switch Expressions & Statements questions

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

Open OCP Java SE 17

Other topics in this pack