Shortening Code with Pattern Matching Flashcards
Java 16 officially introduced pattern matching
with if statements and the instanceof
operator. Pattern matching is a technique of controlling program flow that only executes a section of code that meets certain criteria. It is used in conjunction with if statements for greater program control.
- Java 16
- pattern matching
- if statment
- instanceof operator
- controlling program flow that only executes a section of code that meets certain criteria
- used in conjuction with if statments for greater program control.
void compareIntegers(Number number) { if (number instanceof Integer) { Integer data = (Integer) number; System.out.print(data.compareTo(5)); } }
The variable data in this example is referred to as the pattern variable. Notice that this code also avoids any potential ClassCastException
because the cast
operation is executed only if the implicit instanceof
operator returns true
.
void compareIntegers(Number number) { if (number instanceof Integer data) { System.out.print(data.compareTo(5)); } }
> [!NOTE]
Reassigning Pattern Variables
While possible, it is a bad practice to reassign a pattern variable since doing so can lead to ambiguity about what is and is not in scope.
The reassignment can be prevented with a final modifier, but it is better not to reassign the variable at all.
if (number instanceof Integer data) { data = 10; }
if (number instanceof final Integer data) { data = 10; // DOES NOT COMPILE }
Pattern Variables and Expressions
Pattern matching includes expressions that can be used to filter data out, such as in the following example:
void printIntegersGreaterThan5(Number number) { if (number instanceof Integer data && data.compareTo(5) > 0) System.out.print(data); }
We can apply a number of filters, or patterns, so that the if statement is executed only in specific circumstances. Notice that we’re using the pattern variable in an expression in the same line in which it is declared.
Subtypes
The type of the pattern variable must be a subtype
of the variable on the left side of the expression. It also cannot be the same type. This rule does not exist for traditional instanceof operator expressions, though.
Consider the following two uses of the instanceof operator:
Integer value = 123; if (value instanceof Integer) {} if (value instanceof Integer data) {} // DOES NOT COMPILE
While the second line compiles, the last line does not compile because pattern matching requires that the pattern variable type Integer be a strict subtype of Integer.
> [!NOTE]
Limitations of Subtype Enforcement
The compiler has some limitations on enforcing pattern matching types when we mix classes and interfaces, which will make more sense after you read Chapter 7, “Beyond Classes.” For example, given the non-final class Number and interface List, this does compile even though they are unrelated:
Number value = 123; if (value instanceof List) {} if (value instanceof List data) {}