Java SE 16: Pattern Matching for instanceof

Many developers over the years got familiar with the following the operator “instanceof”. Although the usage of the conditional operator “instanceof” may be considered as bad practice it is still very effective way how to distinguish the Java instance type.  The previous implementation of “instanceof” operator has been causing a bit controversy due to its construct.  Aside of others it created a boilerplate code

if (obj instanceof Vehicle) {
    Vehicle s = (CarVehicle) obj;       
} 

Java SE 16 comes with a significant improvement to this construct. It is called “instanceof pattern matching”. It combines a predicate with a set of local pattern variables. Local pattern variables provide a compile time safety!

Let’s briefly review its power on examples bellow and create a file “PatternMatchinMain.java”.

Requirement:

  • Java JDK 16
  • Favorite Text Editor
  • Command-Line
$ java -version

output: 
openjdk version "16" 2021-03-16
OpenJDK Runtime Environment (build 16+36-2231)
OpenJDK 64-Bit Server VM (build 16+36-2231, mixed mode, sharing) 

To execute a simple java program we use “JEP-330: Launch Single-File Source-Code Programs” feature.  We create a following skeleton and keep it extending and compiling as some of example causes a compile exceptions. 

import java.util.List;

public class PatternMatchingMain {

    private static interface Vehicle {}
    private static class CarVehicle implements Vehicle {
        public int getMaxSpeed(){
            return 42;
        }
    }
    private static class BusVehicle implements Vehicle {}
    private static final class TruckVehicle implements Vehicle {}
    
    public static void main(String[] args){
        ...
        System.out.println("Examples, JEP 394: Pattern Matching for instanceof");
        <ADD CODE HERE AND RUN>
        ...
    }
} 

As the first we review already existing implementation of the “instanceof” operator with potential issue of using it!


Vehicle vehicle1 = new CarVehicle();
if(vehicle1 instanceof Vehicle){
    System.out.println("Example 1, Compiler is fine ");
}

if(vehicle1 instanceof List){
    System.out.println("Example 2, Compiler is not able to distinguish at type");
}

/*
 * COMPILER ERROR due to the type incompatibility
 * 
 * output: incompatible types: TruckVehicle cannot be converted to List
 */

TruckVehicle vehicle2 = new TruckVehicle();
if(vehicle2 instanceof List){
    System.out.println("Example 3, Compiler ERROR,  TruckVehicle is final type");
} 

As you can spot in case of instance of “TruckVehicle” “vehicle2” the compiler properly distinguish correctly that “vehicle2” type is definitely not an instance of the List interface. In case of “vehicle1” type compiler is not able to evaluate. It is important to remember that compiler possibilities are limited in case of interfaces. When the class is not declared final, case of “TruckVehicle” it’s final ,  the class may potentially inherit through a sub-subclasses such interface!

Object obj = "JEP 394";
if(obj instanceof String t1){
    System.out.println("Example4, t1:" + t1);
}

if(vehicle1 instanceof CarVehicle v1){
    System.out.println("Example5, v1, maxSpeed:" + v1.getMaxSpeed());
}

if(vehicle1 instanceof CarVehicle v1 && v1.getMaxSpeed() > 22) {
    System.out.println("Example6, v1, maxSpeed:" + v1.getMaxSpeed());    
} 

The examples above show how new construct eliminates the boilerplate code and enforce a code safety. The parent variable names can be re-used but they can not be defined in the similar scope as shows the example bellow: 

/*
 * Compiler ERROR: variable v1 is already defined in method main(String[]) 
 */
if(vehicle1 instanceof CarVehicle v1 && v1.getMaxSpeed() > 22) {
    if( vehicle1 instanceof CarVehicle v1 && v1.getMaxSpeed() < 100){
        System.out.println("Example6, v1, maxSpeed:" + v1.getMaxSpeed());
    }
} 

Conclusion

The examples above have shown the power of the new “instanceof” construct with pattern matching.  They also shown some potential dangerous usages. 

Happy Coding!  

Java JDK details: Versions and details 
Main: Java tutorials