Tuesday, April 5, 2022

instanceof Operator in Java With Examples

In your application sometimes you may have a situation where you would like to check the type of an object during run time. For that you can use instanceof operator in Java.

Syntax of Java instanceof operator is as follows.

obj instanceof type;

Here obj is refrence to an object and type is a class type. This check will return true if obj is of the class type given on the right hand side of the instanceof operator or can be cast into that type safely.

When to use Java instanceof operator

An object can only be cast to its own class or one of its super-type, if you try to cast to any other object you may either get a compile-time error or a class-cast exception (run-time).

In order to avoid that error it is better to check whether the object can be cast to that type safely or not. For that you can use instanceof operator.

It is evidently important to use instanceof operator when you have a parent-child relationship, an inheritance hierarchy with a parent class and more than one child classes.

A super type can hold reference to an object of itself or the sub-types. But doing the opposite, when you want a conversion from super-type to sub-type, you will need type casting.

As example, if there is class A and two child classes class B and class C, then object of type A can refer to object of type B or to an object of type C.

A a;
B b = new B();
C c = new C();
a = b; // permitted
a = c; // permitted
b = a; // results in compile-time error (Type mismatch)

This (a = b) or (a = c) can be done with out any need of casting.
But doing the opposite (b = a;) will need casting. What you will have to do is-

b = (B) a;
a = c;

and for class C object c = (C)a;

Now, in your application if you have a hierarchy where there are many child classes, type casting may cause problem as you may not be knowing the actual type of the object. In this case you need instanceof operator to check the type of the object before doing the casting.

Java instanceof operator Example

In the example there is an interface Shape which is implemented by two classes Triangle and Rectangle. Using the references of these classes type checks are performed with the help of Java instanceof operator.

interface Shape{
  public void area();
}

class Triangle implements Shape{
  // area method implementation for Triangle class
  public void area(){
   System.out.println("In area method of Triangle");
  }
}

class Rectangle implements Shape{
  // area method implementation for Rectangle class
  public void area(){
   System.out.println("In area method of Rectangle");
  }
}

public class InstanceOfExample {

 public static void main(String[] args) {
  Triangle t = new Triangle();
  Rectangle r = new Rectangle();
  Shape s = t;
  // returns true
  if(t instanceof Shape){
   System.out.println("Triangle is of type Shape");
  }
  // returns true
  if(r instanceof Shape){
   System.out.println("Rectangle is of type Shape");
  }
  // returns false
  if(s instanceof Rectangle){
   System.out.println("Triangle is of type Rectangle");
  }
 }
}

Output

Triangle is of type Shape
Rectangle is of type Shape

Java example using instanceof operator and casting

Here I have a class hierarchy where Payment is an interface and there are two classes CashPayment and CardPayment implementing the Payment interface.

Payment interface

public interface Payment {
 public boolean proceessPayment(double amount);
}

CashPayment class

import org.netjs.examples.interfaces.Payment;

public class CashPayment implements Payment {
 @Override
 public boolean proceessPayment(double amount) {
  System.out.println("Cash payment done for Rs. " + amount);
  return true;
 }
}

CardPayment class

import org.netjs.examples.interfaces.Payment;

public class CardPayment implements Payment {

 @Override
 public boolean proceessPayment(double amount) {
  System.out.println("Card Payment done for Rs. " + amount);
  return true;
 }
 
 public void printSlip(){
  System.out.println("Printing slip for payment" );
 }
}

Note that in CardPayment class there is an extra method printSlip().

As a good programmer you are trying to write a good, object-oriented principles following code and want to have proper polymorphism. In order to achieve that you will refer the instances of child classes CardPayment and CashPayment through the super type instance Payment. Only to call printSlip() method you will need downcasting to the child class. Something similar to what is written below.

import org.netjs.examples.interfaces.Payment;

public class PaymentDemo {

 public static void main(String[] args) {
  PaymentDemo pd = new PaymentDemo();
  Payment payment = new CashPayment();
  pd.doPayment(payment, 100);
  payment = new CardPayment();
  pd.doPayment(payment, 300);
 }
 
 public void doPayment(Payment pd, int amt){
  pd.proceessPayment(amt);
  //downcasting
  CardPayment cardPay = (CardPayment)pd;
  cardPay.printSlip();
 }
}

But running this will throw ClassCastException at run time -

Cash payment done for Rs. 100.0
Exception in thread "main" java.lang.ClassCastException: org.netjs.examples.impl.CashPayment cannot be cast to org.netjs.examples.impl.CardPayment
 at org.netjs.examples.impl.PaymentDemo.doPayment(PaymentDemo.java:17)
 at org.netjs.examples.impl.PaymentDemo.main(PaymentDemo.java:10)

What went wrong here is that you want to call printSlip() method only if the instance is of type CardPayment. But doPayment() method of the PaymentDemo class is having Payment (Super class) as the argument which can refer to instances of CardPayment as well as CashPayment.

Here you can use instanceof operator to check if passed reference is actually of type CardPayment, if yes, then only call the printSlip() method.

Code after including instanceof operator

public class PaymentDemo {

 public static void main(String[] args) {
  PaymentDemo pd = new PaymentDemo();
  Payment payment = new CashPayment();
  pd.doPayment(payment, 100);
  payment = new CardPayment();
  pd.doPayment(payment, 300);
 }
 
 public void doPayment(Payment pd, int amt){
  pd.proceessPayment(amt);
  if (pd instanceof CardPayment){
   CardPayment cardPay = (CardPayment)pd;
   cardPay.printSlip();
  }
 }
}

Output

Cash payment done for Rs. 100.0
Card Payment done for Rs. 300.0
Printing slip for payment

Here note how instanceof operator is used to check the type and if appropriate type is there then only condition gets fulfilled.

Points to remember

  1. An object can only be cast to its own class or one of its super-type.
  2. instanceof operator in Java provides you a way to get run time information about the type of the object.
  3. instanceof operator, if used, should be used sporadically. If you are compelled to use instanceof operator a lot that would mean some inherent flaw in the design of your application.
  4. A use case where use of instanceof operator makes sense is trying to write a generalized logic for a class hierarchy, so that your logic can work for any object of the class hierarchy.

That's all for this topic instanceof Operator in Java With Examples. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Java Basics Tutorial Page


Related Topics

  1. Package in Java
  2. Access Modifiers in Java - Public, Private, Protected and Default
  3. Encapsulation in Java
  4. Polymorphism in Java
  5. Ternary operator in Java With Examples

You may also like-

  1. Association, Aggregation and Composition in Java
  2. Initializer Block in Java
  3. Array in Java With Examples
  4. String Vs StringBuffer Vs StringBuilder in Java
  5. How and Why to Synchronize ArrayList in Java
  6. Difference between HashMap and ConcurrentHashMap in Java
  7. Java ThreadLocal Class With Examples
  8. Spring Bean Life Cycle

1 comment:

  1. The Points to remember section in all the articles of this website is awesome and clever feature.

    ReplyDelete