
Pattern matching for instanceof operator was released as preview feature in Java 14, 15 and it is finalized in Java 16. Pattern Matching helps to reduce boilerplate code and your code will be less error-prone. To understand pattern matching functionality, let’s examine the following code.
You can see 2 usages of instance of operator below: First one is not using Pattern Matching feature (before Java 16), and the second one is using pattern matching feature.
//Before Pattern Matching
if (obj instanceof String) {
String str = (String) obj;
System.out.println(str);
}
//After Pattern Matching
if (obj instanceof String str) {
System.out.println(str);
}
Most of the Java programmers are familiar with the first usage. First type of obj variable is checked with instanceof operator (Line 2). If the test condition is true (obj is a String), then it’s cast to String and assigned to local variable str (Line 3).
In the second usage, Pattern Matching feature is used. 3 Operations are performed in one line (Line 8): type checking of obj instance, casting obj to String, and assigning it to a new local variable str. Pattern matching makes the code more concise.
Scope
The variable introduced by instanceof operator is a special type of local variable. Scoping rules are similar to local variables. For instance, pattern variable str can be accessed inside the if block it’s defined, but it cannot be accessed from outside the if block.
if (obj instanceof String str) {
System.out.println(str);
// str variable can be used here
}
// str variable cannot be accessed here
Since pattern variable is a local variable, you cannot create 2 local variables with same name. Following code gives compiler error, because a local variable str is already created on the first line.
String str="";
// Compiler Error:
// Variable 'str' is already defined in the scope
if (obj instanceof String str) {
System.out.println(str);
}
Null Check
Null check is already included in instanceof test, you don’t need to worry about null values. Pattern will only match when obj is not null, so pattern variable str will only be created for non-null values.
Overriding equals() method
Pattern matching feature can be used to simplify overriding equals method (Equals and Hashcode Methods in Java). The code below shows 2 implementations of equals method. Both implementations are identical in practice, but second implementation uses instanceof pattern matching and it’s more readable.
//Before Pattern Matching
@Override
public boolean equals(Object obj)
{
if (obj instanceof Rectangle) {
Rectangle rect = (Rectangle)obj ;
return rect.width == width && rect.height == height ;
} else {
return false;
}
}
//After Pattern Matching
@Override
public boolean equals(Object obj)
{
return (obj instanceof Rectangle rect)
&& rect.width == width
&& rect.height == height;
}