Why does this code throw a ClassCastException at runtime ? class base{} class derived extends base{} class test { public static void main(String arg[]) { derived d = ( derived)new base(); } }
Hi Chandan, The ClassCastException is because you are performing an assignment that is downward in the heirarchy. base --> derived You are trying to create a base and cast it to its own subclass. You can only do that if you have previously stored the subclass into the base. For example, the following will work: base b; derived d = new derived(); b = d; d = (derived) b; The above will work because we have stored an object reference to derived into base b. A good metaphor of your example is that you buy a Volkswagon and you really want a Mercedes! Regards, Manfred.
The main point to remember is that when you declare something like <pre> A a = new A(); </pre> 'a' is a reference or handle to an instance of class A. Once created, an Object's type does not change. When you cast, you are casting the reference, not the object itself. It's like you're telling the compiler to treat the object as something else but remember, "A rose by any other name is still a rose" and "You can't pretend to be something you're not." IOW, no matter how many times you cast references to an object from one form to another, you will still have the same object. And you can't refer to an object as something that it's not. So, given the following: <pre> 1. class Car {} 2. class Roadster extends Car {} 3. class Z3 extends Roadster {} 4. class Miata extends Roadster() 5. 6. Z3 beemer = new Z3(); 7. Car theCar = beemer; // OK 8. Roadster bmw = (Roadster)theCar; 9. Z3 myCar = (Z3)bmw; (I wish!) 10. 11. Z3 coolCar = new Roadster(); // compile-time error 12. Roadster mazda = new Miata(); 13. mazda = (Miata)theCar; // runtime error </pre> line 6 creates a new Z3 object and points beemer to it. line 7 declares a reference to a Car object and points it to the same object the beemer points to. This legal because the object is a Car (it descends from Car). line 8 declares a reference to a Roadster and points it to the same object that theCar points to. The cast is like telling the compiler "Take this reference to a Car and think of it as a reference to a Roadster." The compiler, trusting you to know what you are doing, accepts this. The Java VM is not so trusting though and does another check at runtime just to make sure you knew what you are talking about. line 9 does something similar to line 8: it tells the compiler to treat the Roadster reference as a reference to a Z3. This is OK because the object actually is a Z3. line 11 is illegal because a Roadster is not necessarily a Z3 (although a Z3 is a Roadster) line 13 is accepted at compile time because the compiler will trust you when you tell it that "theCar is actually a Miata" but will not pass the test done by the VM at runtime because theCar actually points to a Z3 which is not a Miata. I hope I haven't confused you even more J.Lacar
[This message has been edited by JUNILU LACAR (edited March 05, 2001).]