Next Steps to Pattern Matching in Java with Java 12 and Switch Expressions aka JEP 325
December 30th, 2018 by Micha KopsIt 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.
Contents
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
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:
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
- Java Development Kit (JDK) 12 Early Access Preview
- JEP 325 – Switch Expressions (Preview)
- JEP 305 – Pattern Matching for instanceof (Preview)
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: functional, instanceof, java-12, java12, jep-305, jep-325, pattern-matching, switch-expressions