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:
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:
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.
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.
Example
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