Study guide

2.2 Switch Statements and Switch Expressions

Oracle Java SE 21 Developer 1Z0-830

Track your progress as you read

Finished sections get a check mark.

1 Chapter 1: Java Basics, Primitive Types, and Operators

1.1 Program Structure, Primitives, Literals, Scopes, and var 1.2 Operators, Precedence, and Type Casting 1.3 Strings, Text Blocks, and StringBuilder 1.4 Date and Time APIs (java.time)

2 Chapter 2: Controlling Program Flow & Pattern Matching

2.1 Conditional Logic: if-else and Ternary Operators 2.2 Switch Statements and Switch Expressions 2.3 Pattern Matching for switch and instanceof 2.4 Loops and Branching Statements

3 Chapter 3: Object-Oriented Design & Class Architecture

3.1 Class Declarations, Constructors, and Object Lifecycle 3.2 Encapsulation and Access Modifiers 3.3 Inheritance, Method Overriding, and Polymorphism 3.4 Abstract Classes and Interfaces 3.5 Nested, Inner, Local, and Anonymous Classes 3.6 Method Overloading, Overload Resolution, and Varargs

4 Chapter 4: Modern Java Data Modeling: Records, Enums, and Sealed Types

4.1 Java Records, Canonical/Compact Constructors, and Component Accessors 4.2 Java Enums: Fields, Methods, and Abstract Constant-Specific Behavior 4.3 Sealed Classes and Interfaces: permits, final, non-sealed, and Hierarchy Architecture 4.4 Advanced Record Patterns (JEP 440), Nested Deconstruction, and Sealed Hierarchy Exhaustiveness

5 Chapter 5: Exception Handling and Annotations

5.1 Exception Hierarchy: Checked vs. Unchecked Exceptions 5.2 Exception Handling: try, catch, finally, and Multi-Catch 5.3 Resource Management: try-with-resources and AutoCloseable 5.4 Custom Exceptions and Best Practices 5.5 Java Annotations: Built-in, Meta-Annotations, and Custom Types

6 Chapter 6: Generics and the Collections Framework

6.1 Generics Fundamentals and Generic Methods 6.2 Wildcards, Type Bounds, and Type Erasure 6.3 Core Collections: Lists, Sets, Queues, and Maps 6.4 Sequenced Collections in Java 21 6.5 Sorting, Comparable, and Comparator 6.6 Arrays: Creation, Multidimensional Forms, and the Arrays Utility Class

7 Chapter 7: Functional Programming & Lambda Expressions

7.1 Built-in Functional Interfaces in java.util.function 7.2 Lambda Expressions, Variable Scopes, and Effectively Final 7.3 Method References: Four Varieties and Edge Cases 7.4 Working with java.util.Optional

8 Chapter 8: The Stream API and Data Pipelines

8.1 Stream Creation and Intermediate Operations 8.2 Terminal Operations and Reductions 8.3 Advanced Collectors, Grouping, Partitioning, and Teeing 8.4 Primitive Streams and Parallel Stream Processing

9 Chapter 9: Concurrency, Multithreading, and Virtual Threads

9.1 Thread Fundamentals, Creation, and Lifecycle 9.2 Thread Safety, Synchronization, and the Java Memory Model 9.3 Concurrency Utilities: ExecutorService, Callable, and Future 9.4 Concurrent Collections, Atomics, and Explicit Locks 9.5 Virtual Threads in Java 21 (Carrier Threads, Pinning, and Best Practices)

10 Chapter 10: The Java Platform Module System (JPMS)

10.1 Module Architecture and module-info.java Declarations 10.2 Module Directives: requires, exports, opens, provides, and uses 10.3 Modular Compilation, Packaging, and CLI Execution 10.4 Module Types, Migration Strategies, ServiceLoader SPI, and JLink

11 Chapter 11: Java I/O, NIO.2, and Object Serialization

11.1 Classic Java I/O Streams and Readers/Writers 11.2 Java NIO.2 File API: Path, Paths, and File System Operations 11.3 Advanced NIO.2 Stream Operations and Directory Traversal 11.4 Java Object Serialization and Record Serialization

12 Chapter 12: Implementing Localization and Internationalization

12.1 Locales and Resource Bundles 12.2 Formatting and Parsing Numbers, Currencies, Dates, Times, and Messages

2.2 Switch Statements and Switch Expressions

Key Takeaways Explain This Topic AI

Switch selector types are restricted to char, byte, short, int, Character, Byte, Short, Integer, String, and enum types (excluding long, float, double, and boolean).

Traditional switch statements use colon syntax (case X:) and require explicit break statements to avoid fall-through execution.

Switch expressions (standardized in Java 14) utilize arrow syntax (case X ->) to eliminate fall-through and mandate exhaustive coverage of all possible selector values.

The contextual keyword yield returns a value from a multi-statement block inside a switch expression, whereas return exits the enclosing method.

Last updated: September 2026

Switch Statements, Switch Expressions, and Yield

The switch construct in Java has evolved from a legacy C-style branching statement into a versatile, expression-oriented construct. The 1Z0-830 exam tests both classic switch statements and modern switch expressions, including selector data types, fall-through mechanics, constant expressions, the yield keyword, and compiler exhaustiveness checks.

1. Supported Switch Selector Data Types

The type of the switch selector expression determines which features and case labels are valid:

Classic Switch Selector Types (Java 1.0 - Java 20):

Integral Primitives : byte , short , char , int .

Wrapper Classes : Byte , Short , Character , Integer .

Strings : java.lang.String (supported since Java 7).

Enumerations : enum constants (supported since Java 5).

Unsupported Selector Types in Non-Pattern Switch:

long , float , double , boolean (and their respective wrappers Long , Float , Double , Boolean ). Attempting to switch over a long or double without pattern matching yields a compile-time error: incompatible types: possible lossy conversion from long to int .

Pattern Matching Switch Selector Types (Java 21):

In Java 21, pattern matching allows any reference type (including Object , interfaces, and custom record classes) as the selector expression.

2. Classic switch Statements ( : Colon Syntax)

A classic switch statement uses case labels ending with a colon ( : ).

Fall-Through Behavior

Execution enters at the first matching case label and continues sequentially through subsequent case blocks and default until encountering a break , return , throw , or the end of the switch block: int day = 2;

switch (day) {

case 1:

System.out.print("Mon ");

case 2:

System.out.print("Tue "); // Matches day = 2

case 3:

System.out.print("Wed "); // Falls through!

break;

case 4:

System.out.print("Thu ");

default:

  • System.out.print("Weekend ");
  • }
  • // Output: "Tue Wed "
  • Constant Expression Requirements for Case Labels

Every case value in a classic switch must be a compile-time constant expression assignable to the selector type:

  • Literals (e.g., case 1: , case "ACTIVE": )
  • final variables initialized with compile-time constant expressions (e.g., final int MAX = 10; case MAX: )

Enum constants (written without the qualifying enum type name: case ACTIVE: rather than case Status.ACTIVE: ) final int x = 10;

  • int y = 20; // non-final
  • final int z;

z = 30; // blank final, NOT a compile-time constant!

  • int target = 10;
  • switch (target) {
  • case x: // Valid: compile-time constant
  • break;
  • // case y: // COMPILE ERROR: constant expression required
  • // break;
  • // case z: // COMPILE ERROR: constant expression required
  • // break;
  • }
  • Single Shared Lexical Scope

In colon-syntax switch statements, the entire switch block forms a single lexical scope . Local variables declared in one case are in scope for all subsequent cases, which can lead to variable declaration clashes: int mode = 1;

switch (mode) {

case 1:

  • int count = 10; // Declared in switch scope
  • System.out.println(count);
  • break;

case 2:

// int count = 20; // COMPILE ERROR: Variable 'count' already defined in scope

count = 20; // Legal: reassigning the variable declared in case 1!

  • System.out.println(count);
  • break;
  • }

To isolate local variables within a single case, the case body must be wrapped in explicit block braces: case 1: { int count = 10; break; } .

3. Modern switch Expressions ( -> Arrow Syntax)

Introduced in Java 14 (JEP 361), switch expressions treat branching as a value-producing expression.

Arrow ( -> ) Syntax Rules

No Fall-Through : Only the expression, block, or throw statement to the right of the arrow is executed. No break statements are needed or allowed to prevent fall-through.

Multiple Comma-Separated Labels : Multiple values can be combined into a single case label: case 1, 2, 3 -> "Q1"; .

Right-Hand Side Forms :

  • Single expression: case 1 -> "One";
  • Block with yield : case 2 -> { String res = "Two"; yield res; }
  • Exception throw: case 3 -> throw new IllegalArgumentException(); String season = switch (month) {
  • case 12, 1, 2 -> "Winter";
  • case 3, 4, 5 -> "Spring";
  • case 6, 7, 8 -> "Summer";
  • case 9, 10, 11 -> "Autumn";
  • default -> "Invalid month";

}; // Semicolon required when used in assignment!

  • 4. The yield Keyword and Scope Isolation
  • The yield Statement

yield is a contextual keyword (not a reserved identifier) introduced to return values from switch expression blocks: int score = 85;

  • String grade = switch (score / 10) {
  • case 10, 9 -> "A";
  • case 8 -> {
  • System.out.println("Good job!");
  • yield "B"; // Returns "B" as the switch expression result
  • }
  • case 7 -> "C";
  • default -> "F";
  • };
  • yield vs. return vs. break

yield value; : Produces a value for a switch expression block. It cannot be used in a switch statement.

return value; : Exits the enclosing method , NOT just the switch expression. Attempting to return a switch value with return inside a switch expression block will exit the method entirely!

break; : Valid in classic colon switch statements to terminate execution. Using break value; is obsolete syntax from early preview versions and will not compile.

Lexical Isolation with Arrow Syntax

Unlike colon-syntax switch statements, each arrow branch with curly braces {} defines its own independent local variable scope: int val = 1;

  • switch (val) {
  • case 1 -> {
  • int temp = 100;
  • System.out.println(temp);
  • }
  • case 2 -> {

int temp = 200; // Perfectly legal! Isolated scope.

  • System.out.println(temp);
  • }
  • default -> {}
  • }
  • 5. Switch Statement vs. Switch Expression Comparison
  • Feature Classic Switch Statement Modern Switch Expression
  • Syntax Case labels with colon : Arrow -> or Colon : with yield
  • Produces a Value? No (Statement) Yes (Expression)
  • Trailing Semicolon No ( switch (x) { ... } ) Yes when assigned ( var res = switch(x) { ... }; )
  • Fall-Through Yes by default (requires break ) No fall-through with -> arrow syntax
  • Exhaustiveness Not required (unless pattern switch) Strictly required by compiler
  • Multiple Labels Stacked case 1: case 2: Comma-separated case 1, 2 ->
  • Value Return Mechanism N/A -> expr or yield value;
  • Mixed Syntax Illegal to mix -> and : in the same switch block Illegal to mix -> and : in the same switch block
  • 6. Compiler Exhaustiveness Requirements

When switch is used as an expression , the Java compiler requires that it handles all possible values of the selector type:

For primitive types ( int , char , etc.) and String , a default case is almost always mandatory because their domain of values is effectively infinite.

For enum types, if all enum constants are covered, the compiler does not require a default clause. However, if any enum constant is missing and there is no default , compilation fails with the switch expression does not cover all possible input values . enum Status { PENDING, APPROVED, REJECTED }

Status s = Status.PENDING;

// Compiles cleanly without default because all 3 enum values are handled:

  • String text = switch (s) {
  • case PENDING -> "Please wait";
  • case APPROVED -> "Welcome";
  • case REJECTED -> "Access denied";
  • };

Loading diagram... Switch Statement vs Switch Expression Architecture