应该抓住哪个Throwable的子类,哪个不应该?

API doc说从不捕获Throwable子类Error表示exception行为。 它是否意味着Error和Exception之间的隔离是告诉程序员应该捕获哪个子类,哪个不应该? 或者还有更多呢?

一般来说, Error是严重错误的(通常在平台本身内 ),这是你无法想象的。 我唯一一次关心捕捉Error是为了记录它 ,之后我重新抛出。

这非常重要,因为很容易让错误(和运行时exception)以一种永远不会记录的方式传播到调用堆栈中(例如,使用executorService.submit(Runnable)而不监听返回的Future

Error通常是这样的:

  • 内存不足
  • 抽象方法错误(例如,针对不同版本的库运行而不是针对那些构建的库)
  • 断言(即程序员定义的不变量 ,或者应该永远不会发生的事情 – 哈哈!)

然后我会说RuntimeException通常(虽然不总是)指示编程错误:

  • 不检查null或传入null
  • 传入无效参数或允许无效状态
  • 在迭代时修改集合

我通常会建议在这些上快速失败,但这是一个灰色区域; 也许你在将用户输入传递给服务器之前不检查用户输入 – 这值得崩溃你的应用程序!

Checked Exception (即非运行时)应该用于您可以合理地期望在您的代码中合理地(或可想象地)处理的内容。 我个人喜欢检查exception,但由于以相同方式处理不同exception类型所涉及的冗长/重复(即在多个相同的catch块中),这些exception繁琐。 像Scala这样的语言有更好的捕获语法,但是他们也删除了检查exception的概念!

是的,我认为你的分析在这里是正确的 – 你不应该捕获Error因为它们代表了无法恢复的运行时错误,例如OutOfMemoryError

捕获Throwable的唯一原因是,如果您正在运行程序正确操作所不需要的外部第三方代码 – 如果您不信任该代码,请抓住所有内容,如果您获得了您没想到的内容( Throwable )然后禁用该代码并报告它。

另外,区分ExceptionRuntimeException可能是个好主意。