Thursday, September 5, 2019

java.lang.ClassCastException - Resolving ClassCastException in Java

In this article we’ll see what is java.lang.ClassCastException and how to resolve ClassCastException in Java.

ClassCastException in Java

ClassCastException is thrown in a Java application when you try to cast an object to a class of which the original object is not an instance i.e. if the class of which you have an object and the class you are trying to cast that object to are not having a parent-child relationship then casting to that class will result in ClassCastException.

Exception hierarchy for the ClassCastException in Java is as follows-

ClassCastException in Java

Since ClassCastException derives from RuntimeException that means it is an unchecked exception and there is no need to explicitly handle it using try-catch block.

ClassCastException is closely associated to how type casting is done. You can refer this post Type Casting in Java to get better understanding of type casting in Java.

ClassCastException was quite frequently seen before Java generics came into the picture. When collections were not type safe and you needed to explicit cast the elements when retrieving them from the collection was the fertile ground for the ClassCastException.

ClassCastException Java example

This example shows a scenario where ClassCastException is thrown. 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().

You do want to follow proper object oriented programming so you 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.

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();
 }
}

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)

When instance of CardPayment is passed to Payment reference there is no problem in downcasting it. There is a problem when instance of CashPayment is passed, widening the reference to Payment is ok but attempting to cast it to CardPayment is not possible as there is no parent-child relationship between these two classes. Both of them are child classes of Payment and instances of both of these classes are of type Payment but not interchangeable with each other.

Resolving ClassCastException in Java

To ensure that ClassCastException is not thrown you should check for the type of instance using instanceof operator in Java.

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 casting is done only if correct instance type is found thus avoiding ClassCastException.

That's all for this topic java.lang.ClassCastException - Resolving ClassCastException in Java. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. java.lang.ClassNotFoundException - Resolving ClassNotFoundException in Java
  2. Exception Propagation in Java Exception Handling
  3. finally Block in Java Exception Handling
  4. final Vs finally Vs finalize in Java
  5. Java Exception Handling Interview Questions And Answers

You may also like-

  1. matches() method in Java String
  2. Inheritance in Java
  3. AutoBoxing And UnBoxing in Java
  4. Reflection in Java - Getting Constructor Information
  5. Enum Type in Java
  6. Matrix Addition Java Program
  7. Spring NamedParameterJdbcTemplate Select Query Example
  8. Magic Methods in Python With Examples

1 comment:

  1. The ClassCastException thrown to indicate that your code has attempted to cast an object to a subclass of which it is not an instance. Casting only works when the casted object follows an is a relationship to the type you are trying to cast to.

    When will be ClassCastException is thrown:

    When you try to cast an object of Parent class to its Child class type, this exception will be thrown.

    When you try to cast an object of one class into another class type that has not extended the other class or they don't have any relationship between them.


    ReplyDelete