The following code snippet will result in a run-time:
class Vehicle {
public void printSound() {
System.out.print("vehicle");
}
}
class Car extends Vehicle {
public void printSound() {
System.out.print("car");
}
}
class Bike extends Vehicle {
public void printSound() {
System.out.print("bike");
}
}
public class Test {
public static void main(String[] args) {
Vehicle v = new Car();
Bike b = (Bike) v;
v.printSound();
b.printSound();
}
}
My question is: why does that result in a run-time error but not a compilation error? Shouldn't the compiler know that 'v' is already a 'Car' and cannot be cast into a 'Bike'?
In theory, it would be possible for a compiler to say to itself: "v
is local variable, that is assigned to be a Car
. At no point prior to the attempted cast to Bike
does it change its value, and there is no way for Car
to be successfully cast to Bike
. Therefore, this is an error."
However, I know of no Java compiler that will do that analysis for you. It's really only worthwhile in the simplest of cases. Instead, the behavior is that the compiler sees the cast, and reasons that it is possible to cast a Vehicle
to a Bike
, and so it allows it.
In general, that's what a cast means: it tells the compiler that even though this assignment might fail, you're pretty certain that it won't. In exchange for allowing the code to compile, you assume the risk of a run-time exception.
Casting from super class may work, so it is allowed (during compilation). Casting from a totally different class is not allowed, for example:
Integer a = 1;
String b = (String)a; // compile error
String b = (String)(Object)a; // runtime error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With