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.
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 RuntimeEnvironment(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-source12 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 GitHub repository, fork it there or clone it using Git:
git clone https://github.com/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