Java Pattern Matching with instanceof Operator: A Guide to Type Checking

Discover how Java 14 introduced the enhanced instanceof operator for more concise type checking and variable binding. Learn about its syntax and practical applications in your Java programs, as this feature became standard in Java 17, streamlining your coding practices.



Java - Pattern Matching with instanceof Operator

Java 14 introduced the instanceof operator with type test pattern as a preview feature. This allows for a more concise syntax for type checking and binding variables. This feature became standard in Java 17.

Syntax with Enhanced instanceof Operator

In the following code snippet, we use the instanceof operator to test if a person object is an Employee and simultaneously assign the person object to an Employee reference e, which can then be used to perform operations on the Employee object:

Code Snippet

if (person instanceof Employee e) {
return e.getEmployeeId();
}

Syntax without Enhanced instanceof Operator

Prior to this enhancement, developers had to typecast the object as shown below:

Code Snippet

if (person instanceof Employee) {
// Unnecessary casting
Employee e = (Employee)person;
return e.getEmployeeId();
}

Example - Old Syntax

This example defines the classes Person, Employee, and Manager. The Employee and Manager classes extend the Person class. In the APITester class, we define a method getId() which takes a Person as input and uses the instanceof operator to check if the object is either an Employee or a Manager. Based on the result, it typecasts the object to either Employee or Manager and returns the respective ID.

Code Snippet

package com.tutorialsarena;

public class APITester {
public static void main(String[] args) {
    // Create a Manager Instance   
    Person manager = new Manager(23, "Robert");
    // Get and print Id of the manager
    System.out.println(getId(manager));
}
// using instanceof operator
// to test type of Person to be Employee or Manager
public static int getId(Person person) {
    // If person is Employee, assign it to e
    // in next statement	  
    if (person instanceof Employee) {
        // Unnecessary typecasting	  
        Employee e = (Employee)person;	  
        return e.getEmployeeId();
    } 
    // If person is Manager, assign it to m
    // in same statement	
    else if (person instanceof Manager) {
        // Unnecessary typecasting	  
        Manager m = (Manager)person;
        return m.getManagerId();
    }
    return -1;
}
}
abstract sealed class Person permits Employee, Manager {
String name;
String getName() {
    return name;
}
}
final class Employee extends Person {
String name;
int id;
Employee(int id, String name){
    this.id = id;
    this.name = name;
}
int getEmployeeId() {
    return id;
}
}
non-sealed class Manager extends Person {
int id;
Manager(int id, String name){
    this.id = id;
    this.name = name;
}
int getManagerId() {
    return id;
}
}

Output


23

Example - New Syntax

This example is similar to the previous one but utilizes the enhanced instanceof syntax. The getId() method tests the type of Person and directly assigns the object to Employee or Manager without typecasting.

Code Snippet

package com.tutorialsarena;

public class APITester {
public static void main(String[] args) {
    // Create a Manager Instance   
    Person manager = new Manager(23, "Robert");
    // Get and print Id of the manager
    System.out.println(getId(manager));
}
// using instanceof operator
// to test type of Person to be Employee or Manager
public static int getId(Person person) {
    // If person is Employee, assign it to e
    // in same statement	  
    if (person instanceof Employee e) {
        return e.getEmployeeId();
    } 
    // If person is Manager, assign it to m
    // in same statement	
    else if (person instanceof Manager m) {
        return m.getManagerId();
    }
    return -1;
}
}
abstract sealed class Person permits Employee, Manager {
String name;
String getName() {
    return name;
}
}
final class Employee extends Person {
String name;
int id;
Employee(int id, String name){
    this.id = id;
    this.name = name;
}
int getEmployeeId() {
    return id;
}
}
non-sealed class Manager extends Person {
int id;
Manager(int id, String name){
    this.id = id;
    this.name = name;
}
int getManagerId() {
    return id;
}
}

Output


23