Why can't I downcast in the following code

C

Chad

Given the following...

class X {}
class Y extends X {}
class Z extends X {}

public class Main {

public static void main(String[] args) {
X x = new X();
Y y = new Y();
Z z = new Z();

Y o6 = (Y) x; //<--error
}

}

I get this error...

run:
Exception in thread "main" java.lang.ClassCastException: X cannot be
cast to Y
at Main.main(Main.java:12)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)


I thought I could cast X to Y since they inherited. Why doesn't it
work in this case?


Chad
 
C

Chad

I thought I could cast X to Y since they inherited. Why doesn't it
work in this case?

I thought I could cast X to Y since *they are* inherited. Why doesn't
it work in this case?
 
R

Roedy Green

X x = new X();
Y y = new Y();
Z z = new Z();

Y o6 = (Y) x; //<--error

x references an X object not a Y. Perhaps the compiler is smart enough
to notice that. Perhaps it knows that cast could never succeed.

I would expect it would be happy with code like this where it does not
know precisely what value x has.

dosomething( X x )
{
Y o6 = (Y)x;`
}
--
Roedy Green Canadian Mind Products
http://mindprod.com
It should not be considered an error when the user starts something
already started or stops something already stopped. This applies
to browsers, services, editors... It is inexcusable to
punish the user by requiring some elaborate sequence to atone,
e.g. open the task editor, find and kill some processes.
 
C

Chad

x references an X object not a Y. Perhaps the compiler is smart enough
to notice that. Perhaps it  knows that cast could never succeed.

I would expect it would be happy with code like this where it does not
know precisely what value x has.

    dosomething( X x )
     {
    Y o6 = (Y)x;`
     }


This is taken from my professor's sample midterm. According to him,
the answer is right. I emailed him back saying the compiler generated
an error. He replied back "stop by my office hours sometimes this week
so we can discuss it". That's really not feasible since the midterm is
tomorrow morning.

Chad
 
E

Eric Sosman

Given the following...

class X {}

class Automobile {}
class Y extends X {}

class Toyota extends Automobile {}
class Z extends X {}

class Saab extends Automobile {}
public class Main {

public static void main(String[] args) {
X x = new X();

Automobile x = new Automobile();
Y y = new Y();

Toyota y = new Toyota();
Z z = new Z();

Saab z = new Saab();
Y o6 = (Y) x; //<--error

Toyota o6 = (Toyota) x;
}

}

I get this error...

run:
Exception in thread "main" java.lang.ClassCastException: X cannot be
cast to Y

Exception ... Automobile cannot be cast to Toyota
I thought I could cast X to Y since they inherited. Why doesn't it
work in this case?

Because all Toyotas are Automobiles, but not all Automobiles
are Toyotas.
 
D

Donkey Hottie

24.10.2011 6:16, Eric Sosman kirjoitti:
Because all Toyotas are Automobiles, but not all Automobiles
are Toyotas.

Not true. Toyota has made also sewing machines and forklifts, dunno
other products. :p
 
J

Joshua Cranmer

I thought I could cast X to Y since they inherited. Why doesn't it
work in this case?

The cast is legal Java code and compiles correctly; the fact you got a
runtime exception confirms this. However, you instantiated a runtime
object of type X, which is not a runtime object of type Y. For a clearer
analogue, consider the syntactically similar code:

Object o = "ASDF";
Integer i = (Integer)o;

Do you believe this should work at runtime?
 
L

Lew

Chad said:
Given the following...

class X {}
class Y extends X {}
class Z extends X {}

public class Main {

public static void main(String[] args) {
X x = new X();
Y y = new Y();
Z z = new Z();

Y o6 = (Y) x; //<--error
}

}

I get this error...

run:
Exception in thread "main" java.lang.ClassCastException: X cannot be
cast to Y
at Main.main(Main.java:12)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)


I thought I could cast X to Y since they inherited. Why doesn't it
work in this case?

Inheritance, as you have discovered, does not automatically allow casting.

Upcasting works as you describe; it's downcasting that is tricky. (In Java, an "upcast" is from an inheriting or descendant type to an ancestor type, a "downcast" is from a base or ancestor type to a descendant type.)

To understand this, remember that inheritance (both the 'extends' and the 'implements' variety) represents /is-a/. A descendant thingie /is-an/ ancestor thingie, so in your example,
class X {}
class Y extends X {}
class Z extends X {}

an instance of a 'Y' /is-an/ 'X', but not necessarily would every 'X' /be-a/ 'Y'.
An instance of a 'Z' /is-an/ 'X', but not necessarily would every 'X' /be-a/ 'Z'.

In no way can you say a 'Y' /is-a/ 'Z', nor that a 'Z' /is-a/ 'Y'. Neither one is the parent of the other.

Which is exactly why downcasting is tricky. If you cast an 'X' down to a 'Y', that might actually be a 'Z' you're trying to cast. Oops - 'ClassCastException'. You cannot cast a 'Z' to a 'Y'.

In your case it's worse. You already know that 'x' /is-not-a/ 'Y'. It's a plain old 'X', with nothing of a 'Y' about it. So when you try to cast it down to a 'Y', kaboom!

And by the way, you don't get an error for that, you get an exception for that.
 
L

Lew

Peter said:
He's getting a runtime error, not a compile-time error.

"Some casts can be proven incorrect at compile time; such casts result in a compile-time error."
JLS 5.5

I'd have to bestir myself to confirm this, but I think the OP's situation is in this category.
 
L

Lew

Lew said:
"Some casts can be proven incorrect at compile time; such casts result in a compile-time error."
JLS 5.5

I'd have to bestir myself to confirm this, but I think the OP's situation is in this category.

OK, I am being very confused. The OP posted which it was. Please return to your useful thread already in progress.
 
T

Travers Naran

I thought I could cast X to Y since *they are* inherited. Why doesn't
it work in this case?

The simple answer, Chad, is that x (the variable) is NOT Y (the class).
You can cast a variable to the actual class it is on up. You cannot
turn a parent class into it's child class via casting.

Left as an exercise for the student why this is so.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,076
Latest member
OrderKetoBeez

Latest Threads

Top