When writing code with a lot of conditions, surely you have used either an if-else or a switch statement. But this alternative to the if-else has drawbacks. Some people have even called the switch statement an "anti-pattern".

What's that? An anti-pattern is a common pattern of bad code, i.e. a bad solution to a problem. Programmers try to avoid them in code, since they degrade code quality.

But there is good news: new versions of Java have brought a lot of changes in the language's syntax, and one of those changes affects switch. Intrigued? Then let's go dive in.

To begin with, it is worth clarifying why switch is an anti-pattern. Consider the following code:


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    default:
        seasonNumber = 0;
}

Okay, so it's not yet entirely clear why this is an "anti-pattern".

But what if we add more case blocks and now the code looks like this:


switch (condition) {
    case "DECEMBER":
        seasonNumber = 1;
        break;
    case "JANUARY":
        seasonNumber = 1;
        break;
    case "FEBRUARY":
        seasonNumber = 1;
        break;
    case “MARCH”:
        seasonNumber = 2;
        break;
    case “APRIL”:
        seasonNumber = 2;
        break;
    case “MAY”:
        seasonNumber = 2;
        break;
    default:
        seasonNumber = 0;
}

Let's add a few more lines — the code grows longer. Later we can add more and more lines, and no one will stop us from doing this.

This is the heart of the problem: after initially creating a compact switch statement, we add more and more code to it, taking up more and more space — more than will fit on the screen — and making the code inconvenient to read and maintain.

Difference between the switch statement and switch expression

Java 14 introduced a new and improved switch. It is not a switch statement, but rather a switch expression.

What's the difference, you ask? The difference is that a statement is an instruction that performs a certain set of operations, but an expression is a piece of code that performs some calculation and returns a result.

In other words, now you can save the result of a switch to a variable.

Enough talking. Now let's see what the new switch looks like:


var result = switch(month) {
     case DECEMBER, JANUARY, FEBRUARY -> 1;
     case MARCH, APRIL, MAY -> 2;
    case JUNE, JULY, AUGUST -> 3;
    case SEPTEMBER, OCTOBER, NOVEMBER -> 4;
    default -> 0; 
};

The first thing that catches your eye is how compact the code is. Code that used to take up most of the screen now spans a few lines and looks much more readable.

-> operator

You should also note the -> operator (arrow operator). You may already be familiar with it if you have experience with lambda expressions.

That means now you can write a cool-looking switch in the style of a lambda statement. The arrow operator indicates that the compiler will not proceed to the next case expression (if the current case block lacks a break or return statement), but will instead give you the value of the expression to the right of the arrow.

You can also write code that is not an expression and simply performs certain actions instead of returning anything:


switch(condition) {
    case TRUE, FALSE -> System.out.println("True/false");
  
    default -> System.out.println("Another");
}

Note that switch no longer has a break statement. It was removed in Java 13 and replaced with yield.

What is yield and where can it be used?

When a switch consists of a single line, the -> operator itself returns the value. But what if we have not one, but many lines of code? In such cases, the arrow operator won't return a value, since there are multiple lines, not one.

Maybe we can use return? After all, it is used to return values in Java. Alas, no, return won't work with a switch. So what can we use? There used to be break, but that was removed in Java 13. But in its place we now have yield — a new keyword that helps you return a value from a switch. It is analogous to return statements in methods.


var result = switch(condition) {
//…
case "Hi" -> "greeting"
//…
};  

This code contains a single line, and the -> operator will return "greeting".

But when we have a block of code:


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 Here you need to return "greeting"
	}
};  

The keyword that will help you return a value is yield:


var result = switch(condition) {
//…
case "Hi" -> {
// Your code
 yield "greeting";

	}
};

yield was added in Java 13 for cases where we have more than one line of code in a case block and we need to return a result.

You're probably eager to try out the new switch in your code, but remember that you need Java 14 or higher to do this. With earlier versions, this switch will only be available if you specify the "--enable-preview" flag on the command line, since before version 14 it was part of the technical preview, not a full-fledged part of the language.

That's all for now! See you!