【发布时间】:2016-08-23 13:21:31
【问题描述】:
以下代码由于未处理的异常而无法编译,但在我看来应该没有问题:
class Car {
public void drive() throws Exception {
System.out.println("Driving...");
}
}
public class Sedan extends Car {
public void drive() {
System.out.println("Driving Sedan...");
}
public static void main(String[] args) {
Car c = new Sedan();
c.drive(); //unhandled exception!
}
}
在调用覆盖方法c.drive()时,编译器不应该很明显,不会抛出已检查的异常吗?为什么仅仅因为引用是 Car 类型而不是 Sedan 类型,我们就必须将 drive 视为仍然抛出检查异常?覆盖方法没有!
【问题讨论】:
-
drive可以抛出Exception但main无法处理。 -
因为
c也可能不是Sedan,而throw也可能是Exception。由于throw在Car中定义,您需要处理它。 -
做
Sedan c = new Sedan(); -
编译器不会特意去查看你是否试图欺骗它。您已将超类声明为抛出
Exception,尽管子类可能不会抛出一个,但仍需要处理它,因为它可以抛出一个。 -
编译器在很多情况下都可以推断出该信息。但至关重要的是,并非在所有情况下都如此,这会导致一套规则如此复杂,以至于没有人能完全理解它们。我想我们都同意 JLS 已经足够复杂了。 :)
标签: java overriding checked-exceptions