6

Java 规范要求,如果抛出异常,要么由 try/catch 语句处理,要么用“throws XYZException”声明函数。这有一个 RuntimeException 异常,如果它被抛出而没有被捕获,这是可以的。

这听起来像是一个见仁见智的问题,但我想得越多,它似乎就越违反直觉:

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

当我第一次开始使用 Java 时,我认为必须以这种方式捕获所有异常,这是有道理的,因为所有异常都扩展了 Exception。出现 RuntimeException 异常异常:P 似乎违反了 OOP。既然 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 那样丑陋,它就无法工作。

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

4

3 回答 3

9

首先,所有可以抛出的东西的基类是Throwable(不是Exception)。

下面Throwable是两个子类:ExceptionError

下面ExceptionRuntimeException

在这 4 个主要类中,RuntimeException并且Error选中(可能会被抛出而不必声明为被抛出)。

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

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

剩下的所有其他 Throwables,即 的子类Exception,必须声明为 throwed 或 catch。这背后的想法是检查的异常可以“由调用者处理”。例如FileNotFoundException(我们知道这意味着什么,如果我们得到一个应该知道该怎么做)。

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

于 2013-07-13T13:17:29.297 回答
0

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

于 2013-07-13T13:06:32.547 回答
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.

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

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

于 2013-07-13T13:10:35.340 回答