Learn what pattern matching for instanceof is and how to use it since Java 14 (JEP 305). This is a preview language feature in JDK 14.
1. instanceof operator improvement
1.1. Traditional approach
If applications when we need to process a certain type of class, but we have a reference of super class type, then we need to check the type of that instance and cast appropriately.
For example, a Customer
can be of type BusinessCustomer
or PersonalCustomer
. Based on type of customer instance, we may fetch the information based on context.
Customer customer = null; //get this value from some method String customerName = ""; //Old approach if(customer instanceof PersonalCustomer) { PersonalCustomer pCustomer = (PersonalCustomer) customer; //Redundant casting customerName = String.join(" ", pCustomer.getFirstName(), pCustomer.getMiddleName(), pCustomer.getLastName()); } else if(customer instanceof BusinessCustomer) { BusinessCustomer bCustomer = (BusinessCustomer) customer; //Redundant casting customerName = bCustomer.getLegalName(); }
1.2. New approach
Now, with pattern matching with instanceof we can write the similar code in below manner. Here we can reduce the boilerplate code of typecasting (e.g. cast pCustomer
to customer
).
//New approach if(customer instanceof PersonalCustomer pCustomer) { customerName = String.join(" ", pCustomer.getFirstName(), pCustomer.getMiddleName(), pCustomer.getLastName()); } else if(customer instanceof BusinessCustomer bCustomer) { customerName = bCustomer.getLegalName(); }
2. Technical details
2.1. Type test pattern
A pattern is a combination of :
- a predicate that can be applied to a target, and
- a set of binding variables that are extracted from the target only if the predicate successfully applies to it
A type test pattern (used in instanceof
) consists of a predicate that specifies a type, along with a single binding variable.
In the code below, the phrase String s
is the type test pattern:
if (obj instanceof String s) { // can use s here } else { // can't use s here }
2.2. What it does?
The instanceof
operator “matches” the target obj
to the type test pattern if obj
is an instance of String
, then it is cast to String
and assigned to the binding variable s
.
Note that the pattern will only match, and s
will only be assigned, if obj is not null
.
2.3. Complex expressions
When the if
statement grows more complicated, the scope of the binding variable grows accordingly.
For example, when we add &&
operator and another statement then the added statement is only evaluated if instanceof
succeeded and assigned to pCustomer
. Also, the pCustomer
in the true block refers to a field in the enclosing class.
//Works fine if(customer instanceof PersonalCustomer pCustomer && pCustomer.getId() > 0) { customerName = String.join(" ", pCustomer.getFirstName(), pCustomer.getMiddleName(), pCustomer.getLastName()); }
Opposite to above case, when we add ||
operator and another statement then binding variable pCustomer
is not in scope on the right hand side of the ||
operator, nor is it in scope in the true block. pCustomer
at these points refers to a field in the enclosing class.
//Compiler error :: The pattern variable pCustomer is not in scope in this location if(customer instanceof PersonalCustomer pCustomer || pCustomer.getId() > 0) { customerName = String.join(" ", pCustomer.getFirstName(), pCustomer.getMiddleName(), pCustomer.getLastName()); }
Drop me your questions related to Java 14 instanceof pattern matching example.
Happy Learning !!