Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java inheritance downcast ClassCastException

given the following code, I have a question:

class A{}
class B extends A {}
class C extends B{}

public class Test {
    public static void main(String[] args) {
        A a = new A();
        A a1=new A();
        B b = new B();
//        a=b;// ok
//        b=(B)a;// ClassCastException
//        a=(A)a1;  // ok
//        a=a1;  // ok

        a=(B)a1;  // compiles ok, ClassCastException
    }
}

My question is with the line in bold. My understanding is that for the code to compile, it just needs to be satisfied that the classes are in the same hierarchy and as a result it may work (up the tree implicit casting, down the tree requires explicit casting). Whenever I have come across ClassCastException it is because the reference was pointing to an object up the tree e.g. a ref of type B pointing to an object of type A.

The line in question appears to be a ref of type A pointing to an object of type A. The cast to (B) obviously is what is causing the ClassCastException. Can someone explain please what it does to effect this?

Note: If a1 was pointing at an object of type B then it works (just tested it). So the downcast is legal regarding the compiler and it can be made to execute without an exception if the reference is pointing at an object of the correct type.

By casting the A ref a1 to a B and assigning it to a, it appears that the A ref a no longer expects to refer to an object of type A but a B?

Thanks, Sean.

PS I know this is a bit unusual, preparation for Java certification. Normally we downcast to the type on the left hand side e.g. b=(B)a; (and I can see why this gives a ClassCastException).

like image 755
Sean Kennedy Avatar asked Jan 23 '26 22:01

Sean Kennedy


2 Answers

All B's are A's, by inheritance. But not all A's are B's. This particular instance isn't, hence the runtime exception.

like image 193
keshlam Avatar answered Jan 25 '26 12:01

keshlam


You are trying to cast a super class reference variable to a sub class type. You cannot do this. Think practical, a super class object cannot contain independent methods (other than the super class' methods) of the sub class.

At run-time you might call a method in the sub class which is certainly not in the super class object.

class A{
  public void foo(){}
}
class B extends A {
  public void bar(){}
}

Now,

A a=new A();
B b=(B)a;
b.bar();

When you call like this the compiler, will only check whether the method bar() existed in the class B. That's it. It doesn't care about what is in the 'object' because it is created at runtime.

But at runtime, as said before there is no bar() method in the object a. b is just a reference that is pointing to object a but a contains only foo() not bar()

Hope you understood. Thank you.

like image 35
JavaTechnical Avatar answered Jan 25 '26 13:01

JavaTechnical



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!