Next Steps to Pattern Matching in Java with Java 12 and Switch Expressions aka JEP 325

December 30th, 2018 by

It is interesting to see how the Java language evolves over time. One thing that I have always missed is pattern matching in a way similar to languages like Scala.

Now there are different JDK Enhancement Proposals (JEP) aiming at bringing us a little bit closer to pattern matching, especially JEP 325 aka Switch Expressions that are included in the current Java 12 preview or JEP 305 aka Pattern Matching for instanceof.

In the following article, I’d like to demonstrate how to use switch expressions in our applications.

Java 12 Switch Example

Java 12 Switch Example

 

Installing Java 12

Simply download the binaries from https://jdk.java.net/12/, extract them and add them to your PATH or/and configure your IDE for this new SDK.

Running java -version should produce a similar output to this one:

java -version
openjdk version "12-ea" 2019-03-19
OpenJDK Runtime Environment (build 12-ea+25)
OpenJDK 64-Bit Server VM (build 12-ea+25, mixed mode, sharing)

Switch Expressions Example

A simple example matching on months of the year. Please note that..

  • the fall-through semantic is avoided, so there is no need to write explicit breaks
  • the switch expressions now has a return value
For more detailed information about this preview feature, please consult the JEP 325 docs here.
package com.hascode.tutorial;
 
import static com.hascode.tutorial.ExampleWithNewSwitch.Month.*;
 
public class ExampleWithNewSwitch {
  enum Month {
    JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;
  }
 
  public static void main(String[] args) {
    System.out.printf("%s is winter: %b%n", DECEMBER, isWinter(DECEMBER));
    System.out.printf("%s is winter: %b%n", AUGUST, isWinter(AUGUST));
    System.out.printf("%s is winter: %b%n", NOVEMBER, isWinter(NOVEMBER));
    System.out.printf("%s is winter: %b%n", JUNE, isWinter(JUNE));
  }
 
  static boolean isWinter(Month month){
    return switch(month){
      case NOVEMBER, DECEMBER, JANUARY -> true;
      default -> false;
    };
  }
}

Compiling and Running

As we’re using a preview feature, we need to enable this by specifying the source level and adding –enable-preview as parameter:

javac --enable-preview -source 12 src/com/hascode/tutorial/ExampleWithNewSwitch.java

In addition we may add the parameter -Xlint:preview to gain more information about the preview features used:

javac -Xlint:preview --enable-preview -source 12 src/com/hascode/tutorial/ExampleWithNewSwitch.java
src/com/hascode/tutorial/ExampleWithNewSwitch.java:19: warning: [preview] switch expressions are a preview feature and may be removed in a future release.
    return switch(month){
           ^
src/com/hascode/tutorial/ExampleWithNewSwitch.java:20: warning: [preview] multiple case labels are a preview feature and may be removed in a future release.
      case NOVEMBER, DECEMBER, JANUARY -> true;
                   ^
src/com/hascode/tutorial/ExampleWithNewSwitch.java:20: warning: [preview] multiple case labels are a preview feature and may be removed in a future release.
      case NOVEMBER, DECEMBER, JANUARY -> true;
                             ^
src/com/hascode/tutorial/ExampleWithNewSwitch.java:20: warning: [preview] switch rules are a preview feature and may be removed in a future release.
      case NOVEMBER, DECEMBER, JANUARY -> true;
                                       ^
src/com/hascode/tutorial/ExampleWithNewSwitch.java:21: warning: [preview] switch rules are a preview feature and may be removed in a future release.
      default -> false;
              ^
5 warnings

When running the compiled code, we need to enable preview features again:

java --enable-preview com.hascode.tutorial.ExampleWithNewSwitch

So the example above could be run like this:

java -cp src --enable-preview com.hascode.tutorial.ExampleWithNewSwitch
DECEMBER is winter: true
AUGUST is winter: false
NOVEMBER is winter: true
JUNE is winter: false

Using your IDE of choice, you might need to enable preview features there, too … this is an example for setting the language level to Java 12 with preview features enabled in IntelliJ IDEA:

Activating preview features in IntelliJ

Activating preview features in IntelliJ

JEP-305 aka Pattern Matching for instanceof

This enhancement proposal allows basic pattern matching for instanceof checks that spares us the typical casting that follows an instanceof check.

if(obj instanceof String str){
  // use string variable str
} else {
  // ...
}

For more detailed information, please consult the JEP-305 preview specs here.

Tutorial Sources

Please feel free to download the tutorial sources from my Bitbucket repository, fork it there or clone it using Git:

git clone https://bitbucket.org/hascode/java12-switch.git

Resources

Troubleshooting

  • com/hascode/tutorial/Main.java:8: error: switch expressions are a preview feature and are disabled by default.
    int x = switch (in) {
    ^
    (use –enable-preview to enable switch expressions)
    com/hascode/tutorial/Main.java:9: error: switch rules are a preview feature and are disabled by default.
    case “three” -> 3;
    ^
    (use –enable-preview to enable switch rules)
    2 errors
    “: Add –enable-preview as parameter for the compiler invocation
  • Error: LinkageError occurred while loading main class com.hascode.tutorial.Main
    java.lang.UnsupportedClassVersionError: Preview features are not enabled for com/hascode/tutorial/Main (class file version 56.65535). Try running with ‘–enable-preview’
    “: Add –enable-preview to the invocation of java

Tags: , , , , , , ,

Search
Categories