Throwable 的哪个子类应该被捕获,哪个不应该被捕获?
题
API 文档说永远不要捕获 可投掷 子类 错误 这意味着异常行为。这是否意味着Error和Exception之间的隔离是为了告诉程序员哪个子类应该被捕获,哪个子类不应该被捕获?或者还有更多的内容?
解决方案
一般来说, Error
有严重错误(通常 在平台本身内)这是你无法想象的处理。我唯一关心的是捕捉 Error
是为了 记录它, ,然后我重新抛出。
这非常重要,因为很容易让错误(和运行时异常)以永远不会被记录的方式在调用堆栈中传播(例如使用 executorService.submit(Runnable)
不听返回的 Future
)
Error
通常是这样的:
- 内存不足
- 抽象方法错误(例如针对不同版本的库运行(与构建的库版本不同)
- 断言(即程序员定义的 不变量, ,或者永远不应该发生的事情 - 哈哈!)
那么我会说 RuntimeException
s 通常(尽管并非总是)表示 编程 错误:
- 不检查 null 或传入 null
- 传递无效参数,或允许无效状态
- 在迭代集合时修改集合
我通常会建议在这些问题上快速失败,但这是一个灰色地带;也许您在将用户输入传递到服务器之前没有检查用户输入 - 几乎不值得让您的应用程序崩溃!
已检查 Exception
s(即非运行时)应该用于您可以合理预期发生并在代码中合理(或可以想象)处理的事情。就我个人而言,我喜欢检查异常,但由于以相同方式处理不同异常类型(即,在多个相同的 catch 块中)。像 Scala 这样的语言有更好的 catch 语法,但随后他们删除了概念 检查过 也有例外!
其他提示
是的,我觉得你的分析是正确的在这里 - 因为它们代表运行时错误无法伤愈,如Error
你不应该抓OutOfMemoryError
s。
的唯一原因捕捉Throwable
是,如果你运行的是不需要你的程序的正确运行外部第三方代码 - 如果你不信任的代码,捕捉一切,如果你得到的东西,你没“指望(Throwable
)然后禁用代码和报告。
此外,它可能是一个好主意,Exception
和RuntimeException
之间进行区分。