DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Java Is Greener on Arm
  • Mastering Date/Time APIs: Challenges With Java's Calendar and JDK Date/Time APIs
  • Java 23: What Developers Need to Know

Trending

  • Develop a Reverse Proxy With Caching in Go
  • Scalable System Design: Core Concepts for Building Reliable Software
  • Enhancing Security With ZTNA in Hybrid and Multi-Cloud Deployments
  • Fixing Common Oracle Database Problems
  1. DZone
  2. Coding
  3. Java
  4. Java Switch Expressions For Impatiens

Java Switch Expressions For Impatiens

This is the super-fast guide of Java 12/13 switch expressions. Learn how to use switch expressions in 5 minutes.

By 
Anghel Leonard user avatar
Anghel Leonard
DZone Core CORE ·
Feb. 12, 20 · Analysis
Likes (10)
Comment
Save
Tweet
Share
15.1K Views

Join the DZone community and get the full member experience.

Join For Free

This is the super-fast guide of Java 12/13 switch expressions. Learn how to use switch expressions in 5 minutes.

You may also like: JDK 12: Switch Statements/Expressions in Action

Old-School Switch

Before we have a brief overview of the switch expressions introduced in JDK 12, let's see a typical old-school example wrapped in a method (PlayerTypes is a simple Java enum).

Java
 




x
17


 
1
private static Player createPlayer(PlayerTypes playerType) {
2
  
3
  switch (playerType) {
4
    case TENNIS:
5
      return new TennisPlayer();
6
    case FOOTBALL:
7
      return new FootballPlayer();
8
    case SNOOKER:
9
      return new SnookerPlayer();
10
    case UNKNOWN:
11
      throw new UnknownPlayerException("Player type is unknown");
12
    
13
    default:
14
      throw new IllegalArgumentException(
15
        "Invalid player type: " + playerType);
16
  }
17
}



If we forget about default , then the code will not compile.

The preceding example is acceptable. In the worst-case scenario, we can add a spurious variable (for example, player), some cluttering break statements, and get no complaints if default is missing. So, the following code is an old-school, extremely ugly switch.

Java
 




xxxxxxxxxx
1
24


 
1
private static Player createPlayerSwitch(PlayerTypes playerType) {
2
  
3
  Player player = null;
4
  switch (playerType) {
5
    case TENNIS:
6
      player = new TennisPlayer();
7
      break;
8
    case FOOTBALL:
9
      player = new FootballPlayer();
10
      break;
11
    case SNOOKER:
12
      player = new SnookerPlayer();
13
      break;      
14
    case UNKNOWN:
15
      throw new UnknownPlayerException(
16
        "Player type is unknown");
17
    
18
    default:
19
      throw new IllegalArgumentException(
20
        "Invalid player type: " + playerType);
21
  }
22
  
23
  return player;
24
}



If we forget about default, then there will be no complaints from the compiler side. In this case, a missing default case may result in a null player.

Java 12 Switch Expression

However, since JDK 12, we have been able to rely on the switch expressions. Before JDK 12, switch was a statement, a construct meant to control the flow (for example, like an if statement) without representing the result. On the other hand, an expression is evaluated to a result. Therefore, a switch expression can have a result.

The preceding old-school switch expression can be written in the style of JDK 12 as follows.

Java
 




xxxxxxxxxx
1
14


 
1
private static Player createPlayer(PlayerTypes playerType) {
2
  
3
  return switch (playerType) {
4
    case TENNIS -> new TennisPlayer();
5
    case FOOTBALL -> new FootballPlayer();
6
    case SNOOKER -> new SnookerPlayer(); 
7
    case UNKNOWN -> throw new UnknownPlayerException(
8
      "Player type is unknown");
9
      
10
      // default is not mandatory
11
    default -> throw new IllegalArgumentException(
12
      "Invalid player type: " + playerType);
13
  };
14
}



This time, default  is not mandatory. We can skip it.

The JDK 12 switch is smart enough to signal if switch doesn't cover all possible input values. This is very useful in the case of Java enum values. The JDK 12 switch can detect whether all the enum values are covered, and don't force a useless default if they aren't. For example, if we remove default and add a new entry to PlayerTypes enum (for example, GOLF), then the compiler will signal it via a message, as in the following screenshot (this is from NetBeans).

code snippet

Notice that between the label and execution, we've replaced the colon with an arrow (the lambda-style syntax). The main role of this arrow is to prevent fall-through, which means that only the block of code from its right will be executed. There is no need to use break.

Do not conclude that the arrow turns the switch statement into a switch expression. A switch expression can be used with a colon and break as well, as follows:

Java
 




xxxxxxxxxx
1
14


 
1
private static Player createPlayer(PlayerTypes playerType) {
2
  
3
  return switch (playerType) {
4
    case TENNIS: break new TennisPlayer();
5
    case FOOTBALL: break new FootballPlayer();
6
    case SNOOKER: break new SnookerPlayer();
7
    case UNKNOWN: throw new UnknownPlayerException(
8
      "Player type is unknown");
9
      
10
      // default is not mandatory
11
    default: throw new IllegalArgumentException(
12
      "Invalid player type: " + playerType);
13
  };
14
}



Our example posts switch  over enum , but the JDK 12 switch  can also be used over int , Integer , short , Short , byte , Byte , char , Character , and String .

Notice that JDK 12 brings the switch  expressions as a preview feature. This means that it is prone to changes in the next few releases, and it needs to be unlocked via the --enablepreview command-line  option at compiling and runtime.

The complete example is available on GitHub.

Multiple Case Labels

Before JDK 12, a switch statement allowed a single label per case. Starting with the switch expressions, a case can have multiple labels separated by a comma. Check out the following method that exemplifies multiple case labels:

Java
 




xxxxxxxxxx
1


 
1
private static SportType fetchSportTypeByPlayerType(PlayerTypes playerType) {
2
  
3
  return switch (playerType) {
4
    case TENNIS, GOLF, SNOOKER -> new Individual();
5
    case FOOTBALL, VOLLEY -> new Team();
6
  };
7
}



If we pass to this method TENNIS, GOLF, or SNOOKER, it will return an instance of the Individual class. If we pass FOOTBALL or VOLLEY, it will return an instance of the Team class.

The complete example is available on GitHub.

Statement Blocks

A label's arrow can point to a single statement (as in the examples from the previous two examples) or a curly-braced block. This is pretty similar to the lambda blocks. Check out the following solution:

Java
 




xxxxxxxxxx
1
20


 
1
private static Player createPlayer(PlayerTypes playerType) {
2
  
3
  return switch (playerType) {
4
    case TENNIS -> {
5
      System.out.println("Creating a TennisPlayer ...");
6
      break new TennisPlayer();
7
    }
8
    case FOOTBALL -> {
9
      System.out.println("Creating a FootballPlayer ...");
10
      break new FootballPlayer();
11
    }
12
    case SNOOKER -> {
13
      System.out.println("Creating a SnookerPlayer ...");
14
      break new SnookerPlayer();
15
    }
16
       
17
    default -> throw new IllegalArgumentException(
18
      "Invalid player type: " + playerType);
19
  };
20
}



Notice that we exit from a curly-braced block via break, not return. In other words, while we can return from inside a switch statement, we can't return from within an expression.

The complete example is available on GitHub.

Java 13 Switch Expressions

However, since JDK 13, the break with a value statement is dropped in favor of a yield statement. The rest remains the same. So, using yield we obtain:

Java
 




xxxxxxxxxx
1
14


 
1
private static Player createPlayer(PlayerTypes playerType) {
2
  
3
  return switch (playerType) {
4
    case TENNIS: yield new TennisPlayer();
5
    case FOOTBALL: yield new FootballPlayer();
6
    case SNOOKER: yield new SnookerPlayer();
7
    case UNKNOWN: throw new UnknownPlayerException(
8
      "Player type is unknown");
9
      
10
      // default is not mandatory
11
    default: throw new IllegalArgumentException(
12
      "Invalid player type: " + playerType);
13
  };
14
}



The complete example is available on GitHub.

We also obtain:

Java
 




xxxxxxxxxx
1
20


 
1
private static Player createPlayer(PlayerTypes playerType) {
2
  
3
  return switch (playerType) {
4
    case TENNIS -> {
5
      System.out.println("Creating a TennisPlayer ...");
6
      yield new TennisPlayer();
7
    }
8
    case FOOTBALL -> {
9
      System.out.println("Creating a FootballPlayer ...");
10
      yield new FootballPlayer();
11
    }
12
    case SNOOKER -> {
13
      System.out.println("Creating a SnookerPlayer ...");
14
      yield new SnookerPlayer();
15
    }
16
       
17
    default -> throw new IllegalArgumentException(
18
      "Invalid player type: " + playerType);
19
  };
20
}


In a nutshell, the arrow does not signify an expression instead of a statement. The arrow-form prevents fall-through.

Labels with a colon merely mark an entry point into an execution. From there it continues, even when it passes another label. In  switch , we know this as fall-through. In other words, a  case  label determines where the control flow jumps to, but it needs a  break ,  yield  or  return  to quit flowing through the  switch .

On the other hand, the arrow-form signifies that only the block to its right will be executed. That’s right, no fall-through!

Done! The complete example is available on GitHub.

If you enjoyed this article, then you'll love my book, Java Coding Problems, that entirely dedicated to JDK 8 to JDK 13 features.

Happy coding!


Further Reading

Java 12: Mapping With Switch Expressions

Java Switch Statement

Java (programming language) Java Development Kit Label

Opinions expressed by DZone contributors are their own.

Related

  • Jakarta WebSocket Essentials: A Guide to Full-Duplex Communication in Java
  • Java Is Greener on Arm
  • Mastering Date/Time APIs: Challenges With Java's Calendar and JDK Date/Time APIs
  • Java 23: What Developers Need to Know

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!