In the Part 1, we discussed about improved enum constants as case labels in Java 21. In this article, we will focus on patterns in switch labels.
In general, the value of the selector expression is compared with the case label by an equality test. But this mechanism changes when patterns come at the case label. In this case, label is selected based on the result of pattern matching. Remember, a pattern case label can apply to multiple values. Have a look at the below code snippet:
public class PatternsInSwitchDemo {
static void patternCaseLabelTest(Object obj) {
String selected = switch (obj) {
case StringBuffer sb -> sb.toString();
case CharSequence cs -> cs.toString();
default -> obj.toString();
};
System.out.println("Selected Value: " + selected);
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World!");
CharSequence cs = "Hello Jupiter!";
patternCaseLabelTest(cs);
}
}
In the above code, when the method call patternCaseLabelTest(cs) gets executed, the value of obj
matches the pattern CharSequence cs
, and the expression associated with the label case
is evaluated.CharSequence cs
Now consider the below code:
public class PatternsInSwitchDemo {
static void patternCaseLabelTest(Object obj) {
String selected = switch (obj) {
case StringBuffer sb -> sb.toString();
case CharSequence cs -> {
if (!cs.toString().contains("Jupiter")) {
throw new RuntimeException("Wrong message");
} else {
yield cs.toString();
}
}
default -> {
System.out.println("Inside default");
yield obj.toString();
}
};
System.out.println("Selected Value: " + selected);
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World!");
CharSequence cs = "Hello Jupiter!";
StringBuffer s = new StringBuffer("Hello Netune!");
patternCaseLabelTest(cs);
}
}
In the above code, pay close attention to the below code snippet:
case CharSequence cs -> {
if (!cs.toString().contains("Jupiter")) {
throw new RuntimeException("Wrong message");
} else {
yield cs.toString();
}
}
Here, we are further checking the result of pattern matching before executing the logic associated with that label. We can merge these two tests using guarded pattern case labels as follows:
case CharSequence cs when cs.toString().contains("Jupiter") -> cs.toString();
case CharSequence cs when !cs.toString().contains("Jupiter") -> throw new RuntimeException("Wrong message");
The final program will look like below:
public class PatternsInSwitchDemo {
static void patternCaseLabelTest(Object obj) {
String selected = switch (obj) {
case StringBuffer sb -> sb.toString();
case CharSequence cs when cs.toString().contains("Jupiter") -> cs.toString();
case CharSequence cs when !cs.toString().contains("Jupiter") -> throw new RuntimeException("Wrong message");
default -> obj.toString();
};
System.out.println("Selected Value: " + selected);
}
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("Hello World!");
CharSequence cs = "Hello Plto!";
StringBuffer s = new StringBuffer("Hello Netune!");
patternCaseLabelTest(cs);
}
}
The when clause is optional. This is a Boolean expression. The when clause is known as the guard.
That’s it for this article. We will discuss more on Pattern Matching for Switch in Java 21 in upcoming articles.
If you find any significant errors or want to give me some feedback, feel free to contact me at maliksanjoykumar[@]gmail.com.
Sanjoy Kumar Malik is an experienced software architect and technologist. He is passionate about Cloud Computing, Software Architecture, and System Design. Apart from technology and software, he is an avid LinkedIn networker. You can join his 5.5+ lacs supporters on LinkedIn.