June 28, 2022

ClassCastException in Java and Resolution

ClassCastException in Java is thrown if you try to cast an object to a type of which it is not an instance.

For example consider the following code-

Object l = Long.valueOf("120");
System.out.println(l); //120
Number n = (Number)l;
System.out.println(n); // 120

Here we have a reference of Long value stored in an Object type. Later we cast it to Number which is OK because Number is a super class for Long (Long is also of type Number) so cast from Long to Number can be done with no problem.

Now we change it so that reference of Long value is stored in a Number type. Later we cast it to Integer.

Number l = Long.valueOf("120");
System.out.println(l);
Integer i = (Integer)l;
System.out.println(i);
Output
120
Exception in thread "main" java.lang.ClassCastException: class java.lang.Long cannot be cast to class java.lang.Integer

Cast to Integer results in java.lang.ClassCastException because Long is not of type Integer. Both Long and Integer are of type Number but between Integer and Long casting can’t be done.

When you have Inheritance (parent-child classes) and using run time polymorphism where the super class can store the reference to the child class, in that case when you do type casting to cast an object of one type to another ClassCastException is thrown. Here is another hierarchy of classes to understand when ClassCastException may be thrown.

Class A {
	..
}

class B extends A {
	...
}

class C extends A {
	...	
}

A is the parent class for both class B and class C. With this hierarchy you have the following rules for casting.

  1. You can cast instance of any of the A, B or C to Object as Object is the Super class for all the classes in Java.
  2. You can cast instance of either B or C to A as both B and C are also of type A.
  3. If A holds a reference to instance of type B then you can cast it to B only not C. Same is true for instance of type C too. So this is OK.
    A a = new B();
    System.out.println((B)a);
    
    Not this-
    System.out.println((C)a);
    
    Again, this is ok
    A a = new C();
    System.out.println((C)a);
    
    Not this-
    System.out.println((B)a);
    
  4. Though both B and C are of type A but they are not compatible with each other so cast from B to C or from C to B is not possible.

Java ClassCastException hierarchy

ClassCastException if of type RuntimeException which means it is an unchecked exception.

Exception hierarchy for the ClassCastException in Java is as follows-

Java ClassCastException

How to avoid ClassCastException

With the use of generic Collections and the ensuing type safety one major reason of ClassCastException is already avoided.

Another way of avoiding ClassCastException is to use instanceof operator to ascertain the compatibility of the object before casting it.

class B extends A {
}

class C extends A {
}

public class A {
  public static void main(String[] args) {
    A obj1 = new B();
    A obj2 = new C();
    if(obj2 instanceof B) {
      System.out.println((B)obj2);
    } else {
      System.out.println("Not compatible");
    }
    
    if(obj1 instanceof B) {
      System.out.println((B)obj1);
    } else {
      System.out.println("Not compatible");
    }
  }
}
Output
Not compatible
com.knpcode.programs.B@372f7a8d

That's all for the topic ClassCastException in Java and Resolution. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment