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-
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
You may also like-
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.
ReplyDeleteWhen 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.