public void daysOfMonth(int month) { switch (month) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: System.out.println("this month has 31 days"); break; case 4: case 6: case 9: System.out.println("this month has 30 days"); break; case 2: System.out.println("February can have 28 or 29 days"); break; default: System.out.println("invalid month"); } }You see, this method prints the number of days in a given month. Some months have 31 days, some other have 30 days and the February can have 28 or 29 days.Using fall-through cases like that is unnecessarily verbose. So in Java 14, you can use a new form of switch label that allows multiple constants per case as below:
switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> System.out.println("this month has 31 days"); case 4, 6, 9 -> System.out.println("this month has 30 days"); case 2 -> System.out.println("February can have 28 or 29 days"); default -> System.out.println("invalid month"); }Now, with the new form of switch label “case L ->”, the switch block code looks clearer, more concise and more readable. You can use multiple constants per case to reduce the verbosity, and you don’t have to explicitly use break statement to terminate the case, which leads to less error-prone code (no fall through and no break).In the new form of switch label, code after the arrow label can be an expression, a block or a throw statement. For example:
switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> System.out.println("this month has 31 days"); case 4, 6, 9 -> System.out.println("this month has 30 days"); case 2 -> { Scanner scanner = new Scanner(System.in); System.out.print("Enter year: "); int year = scanner.nextInt(); if (year % 4 == 0) System.out.println("This february has 29 days"); else System.out.println("This February has 28 days"); } default -> throw new IllegalArgumentException("Invalid month"); }
int days = 0; 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: days = 30; break; case 2: days = 28; break; default: throw new IllegalArgumentException("Invalid month"); } // use days...Now with Java 14, we can rewrite the above code neatly as follows:
int days = switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9 -> 30; case 2 -> 28; default -> 0; }; // use days...or:
System.out.println( switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9 -> 30; case 2 -> 28; default -> 0; } );This convenient use of switch block is called switch expression. If the code of a case is a block of code, you can use the yield keyword to return the value for the switch block. For example:
int days = switch (month) { case 1, 3, 5, 7, 8, 10, 12 -> 31; case 4, 6, 9 -> 30; case 2 -> { Scanner scanner = new Scanner(System.in); System.out.print("Enter year: "); int year = scanner.nextInt(); if (year % 4 == 0) yield 29; else yield 28; } default -> 0; }; // use days...Furthermore, you can also use the yield statement in combination with traditional case labels ending with a colon like this:
int days = switch (month) { case 1, 3, 5, 7, 8, 10, 12: yield 31; case 4, 6, 9: yield 30; case 2: { Scanner scanner = new Scanner(System.in); System.out.print("Enter year: "); int year = scanner.nextInt(); if (year % 4 == 0) yield 29; else yield 28; } default: yield 0; }; // use days...But you can’t mix both “case L :” and “case L -> “ in a switch block. The yield keyword is chosen instead of return is to avoid confusion: return exits the method, whereas yield returns value and exits the switch block. Conclusion:Hope this post clears doubts you may have with switch statement and switch expression. I think such enhancements are very useful for programmers as they now can use switch block in more flexible ways – also reducing verbosity of the Java programming language.You can also watch the video version of this tutorial here: References:JEP 361: Switch Expressions (Standard)