java - 在java中,为什么Exception是基类而不是RuntimeException?

时间:2013-07-13 13:00:49

标签: java exception

Java规范要求如果抛出异常,则由try / catch语句处理,或者使用“throws XYZException”声明该函数。这有RuntimeException的例外,如果抛出它而没有被捕获,则可以。

这听起来像是一个意见问题,但我想的越多,它看起来就越反直觉:

为什么我们有一个RuntimeException扩展Exception?

当我第一次开始使用Java时,我认为必须以这种方式捕获所有异常,这是有道理的,因为所有异常都会扩展Exception。有一个RuntimeException异常异常似乎违反了OOP:P。由于RuntimeException使throws变得多余,为什么Java在运行时首先不允许所有异常,只有当你想强制调用者处理那种类型的异常时才添加throws?

示例:

void noThrows() {
    throw new Exception();
}

......没有错误。

void hasThrows() throws AnyBaseOfXYZException {
    throw new XYZException();
}

......没有错误。

void testFunction() {
    hasThrows();
}

...失败,因为“hasThrows”抛出AnyBaseOfXYZException,并且没有处理

void testFunction() {
    try {
        hasThrows();
    } catch (AnyBaseOfXYZException e) {
        ...
    }
}

......没有错误。

我想过可能会出现某种扩展Exception的“CompileTimeException”,但是当你给它足够的思考时,它就不会像RuntimeException那样丑陋。

基本上,除了RuntimeExceptions之外,为什么Java决定强制所有异常都需要throws,除非throws另有说明,否则所有异常都可能是运行时异常?

3 个答案:

答案 0 :(得分:7)

首先,可抛出的所有内容的基类是Throwable(不是Exception)。

Throwable下有两个子类:ExceptionError

Exception下的是RuntimeException

在这4个主要类中,RuntimeExceptionError 未经检查(可能会被抛出而不必被声明为被抛出)。

RuntimeException未经检查背后的想法是,它通常是编程错误,而正常的良好做法应该避免它们(例如ArrayIndexOutOfBoundsExceptionNullPointerException)和要求它们被捕获会使代码大量混乱。

Errors未经检查的原因是,基本上,如果发生这种情况,你无能为力,例如OutOfMemoryError等。

这使得所有其他Throwables,即Exception的子类必须被声明为抛出或捕获。这背后的想法是被检查的异常可以“由呼叫者处理”。例如FileNotFoundException(我们知道这意味着什么,如果我们得到一个,应该知道该做什么)。

Java设计师并不总能做到这一点。检查SQLException,但没有现实的恢复方法 - 我的查询中是否存在语法错误?是数据库拒绝连接?谁知道,但我知道我无法“处理”它。

答案 1 :(得分:0)

在某些情况下,您希望拥有一个catch来捕获所有异常:已选中和未选中。 Java的设计决策允许您使用catch (Exception e) { ... }实现该目标 如果未经检查的异常(扩展RuntimeException的异常)未扩展Exception,那么您必须使用两个catch子句。

答案 2 :(得分:0)

这可能与检查和取消选中异常的主题有关。来自RuntimeException

RuntimeException and its subclasses are unchecked exceptions. Unchecked exceptions 
do not need to be declared in a method or constructor's throws clause if they can 
be thrown by the execution of the method or constructor and propagate outside the
method or constructor boundary.

检查异常是用于程序执行时可恢复的情况。因此强制程序员编写类以在方法定义中声明它是非常有意义的。通过这样做,呼叫者将被迫抓住它或重新投掷它。

但是,取消检查异常是针对不可恢复的情况,因此最好终止。这种情况很少发生(通常在代码仍在开发时发生),因此这通常表示程序员错误或非常致命的错误,通常需要由类编写者修复,并且不能由类的客户端恢复。 / p>