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