Meaningless Drivel is fun!
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes Object casting Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "Object casting " Watch "Object casting " New topic

Object casting

Tosin Adedoyin
Ranch Hand

Joined: Nov 09, 2001
Posts: 43
could someone explain the follwing to me
public class X {
public class Y extends X {
public class Z extends X {
public static void main(String args[]) {

X x = new X();
Y y = new Y();
Z z = new Z();
X xy = new Y(); // compiles ok (up the hierarchy)
X xz = new Z(); // compiles ok (up the hierarchy)

X x1 = y; // compiles ok (y is subclass)
X x2 = z; // compiles ok (z is subclass)

Y y1 = (Y) x; // compiles ok but produces runtime error
Z z1 = (Z) x; // compiles ok but produces runtime error
Y y2 = (Y) x1; // compiles and runs ok (x1 is type Y)
Z z2 = (Z) x2; // compiles and runs ok (x2 is type Z)
Object o = z;
Object o1 = (Y)o; // compiles ok but produces runtime error

why does this
Y y1 = (Y) x; // compiles ok but produces runtime error
Z z1 = (Z) x; // compiles ok but produces runtime error
and this
Y y2 = (Y) x1; // compiles and runs ok (x1 is type Y)
Z z2 = (Z) x2; // compiles and runs ok (x2 is type Z)
Dave Vick
Ranch Hand

Joined: May 10, 2001
Posts: 3244
Yopu have to keep in mind the 'is a' rule. If a class extends or implements something then all objects of that class can be considered as 'is a' object of the class or interface they extended or implemented.
In your questions they will all compile because you are using a valid cast and the compiler cant know that at runtime they wont be valid.
For the two that dont work:
Y y1 = (Y) x;
Z z1 = (Z) x;
the variable x 'is a' x object. You cant cast it to a Y or Z object because it isn't an object of that type.
Check out the campfire story on polymorphism too.
hope that helped

Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
So what you're really asking about it upcasting vs. downcasting and when each is legal, right?
You can check out this section of the JLS for all the details: §15.16 Cast Expressions. However, I'll try to briefly explain.
Always remember that a class that extends another class is said to have an "is a" relationship with that class. In your case, Y "is a" X and Z "is a" X. However, X is not a Y and X is not a Z. The "is a" relationship doesn't go both ways.
When you execute code like this:

We have two distinct cases here. In the fist case, we're performing a downcast (hence the cast is required) on the reference variable x. IN effect, we're telling the compiler, "Look, I know that the variable x is of type X, but I know that, at run-time, it'll reference a variable of type Y, so let's just cast it and do the assignment." Once you've done the cast, the compiler says, "Fine, I trust you - I'll compile this." Without the cast, this wouldn't even compile.
However, when you try to execute that code, a check will be done to make sure that the cast can truly be performed. In this case, it can't. Remember, an X object is not a Y object (it's the other way around). Therefore, a ClassCastException is thrown.
The second case is a little different. In this case, we first assign a reference to an object of type Y to a variable of type X. This is okay as this is a downcast. Downcasts can be done implicitly - that's why no cast expression is required.
Then, in the second line, we're again asking the compiler to trust us and do the upcast, so the code compiles. Again, at runtime, the check is done to see if the cast can really be done. In this case it can because the variable x1 really references an object of type Y. Therefore, you can convert that object to type Y. Hence, no runtime error.
I hope that helps,

SCJP Tipline, etc.
I agree. Here's the link:
subject: Object casting
It's not a secret anymore!