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

标签 java exception

<分区>

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

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

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

当我第一次开始使用 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) {
        ...
    }
}

...没有错误。

我曾想过可能是某种扩展异常的“CompileTimeException”,但是当你对它进行足够的思考时,它就无法正常工作而不像 RuntimeException 一样丑陋。

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

最佳答案

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

Throwable下有两个子类:ExceptionError

Exception下是RuntimeException

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

未检查 RuntimeException 背后的想法是,它通常是一个编程错误,正常的良好做法应该避免它们(例如 ArrayIndexOutOfBoundsExceptionNullPointerException) 并要求捕获它们会使代码变得非常困惑。

未检查 Errors 的原因基本上是,如果发生错误,您无能为力,例如 OutOfMemoryError 等。

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

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

关于java - 在 java 中,为什么 Exception 是基类而不是 RuntimeException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17630436/

相关文章:

java - 如何配置 JMX over SSL 使用的 TLS 版本?

java - 从文本文件中读取第 n 个单词

c++ - Windows默默捕获异常,如何手动处理?

python - 尝试在 pytest 屏幕上打印异常错误

java - Java NoClassDefFoundError(名称错误)

java - 无法捕获异常

java - 如何在 Nashorn 中调用带有参数的匿名函数?

java - ActiveMQ 限制外部服务速率

c++ - C++ 类函数未处理的异常

c# - 异常代码,或检测到 "file already exists"类型的异常