A simple pattern matching demo in java
Pattern matching allows to take a decision based upon a type and to destructure its value. Let’s see it in use:
private void performSend(Sendable sendable) {
switch (sendable) {
case Email email -> emailSender.send(email);
case SMS sms -> smsSender.send(sms);
}
}
Here is how the above method can be invoked:
.performSend(new SMS("+33612345678", "+33687654321", "Hello Tom from Sam", Instant.now()))
There are several ways (and operators) to use pattern matching in java. I have chosen the switch/case
way which is available since java 17.
Here, depending on whether the sendable
parameter to the switch
selector is of type Email
or SMS
, the first or second case
expression will be executed, resulting in a email or a SMS being sent.
Pattern matching has been available in the scala programming language for a long time but is relatively new in java. Before then, it could only be simulated in java by using the instanceof
operator together with a cast, therefore breaking the type-safety of the program.
More information and some theory about pattern matching
In the above example, Email
and SMS
are algebraic data types (ADT) called product types: they can have any number of instances depending on the values passed to their constructor:
public record Email(String to, String from, String subject, String message, Instant date) implements Sendable {
}
public record SMS(String to, String from, String message, Instant date) implements Sendable {
}
They are typically implemented with records in java.
Sendable
is another ADT called the sum type in that it can take a finite number of values. It can be implemented with enums or sealed interfaces:
public sealed interface Sendable permits Email, SMS {
}
You see from the above code that Sendable
can have only two types: Email
and SMS
. This is what allows us to omit the default case
expression here:
switch (sendable) {
case Email email -> emailSender.send(email);
case SMS sms -> smsSender.send(sms);
//No default case here!!
}
Conclusion: We have seen the power of pattern matching in java. I have shown how to use it with the switch/case
syntax. Please check out the official documentation for other syntaxes.
Related links and resources:
- https://github.com/balteo/pattern-matching-demo-java (full code source for above sample)
- https://alvinalexander.com/scala/fp-book/algebraic-data-types-adts-in-scala/ (documentation about ADT)
- https://dev.java/learn/pattern-matching/ (official documentation about pattern matching)