问题描述
以下代码段将导致运行时:
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();
}
}
我的问题是:为什么会导致运行时错误但不是编译错误?如果不是编译器知道, 'V' 已经是 '汽车',并不能转换成 '自行车'?
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'?
推荐答案
理论上,编译器可能会对自己说: v
是局部变量,被指定为 Car
。在尝试转换为之前的任何时候都没有它会改变它的值,并且
Car
成功转换为 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."
但是,我知道没有Java编译器会为你做那个分析。在最简单的情况下,这真的是值得的。相反,行为是编译器看到强制转换,并且可以将 Vehicle
强制转换为 Bike
,所以它允许它。
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.
这篇关于Java转换导致运行时错误而不是编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!