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
另有说明,否则所有异常都可能是运行时异常?
答案 0 :(得分:7)
首先,可抛出的所有内容的基类是Throwable
(不是Exception
)。
Throwable
下有两个子类:Exception
和Error
。
Exception
下的是RuntimeException
。
在这4个主要类中,RuntimeException
和Error
未经检查(可能会被抛出而不必被声明为被抛出)。
RuntimeException
未经检查背后的想法是,它通常是编程错误,而正常的良好做法应该避免它们(例如ArrayIndexOutOfBoundsException
或NullPointerException
)和要求它们被捕获会使代码大量混乱。
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>