为什么捕获RuntimeException不被认为是一个好的编程习惯?

为什么使用catch(Throwable exc) {} RuntimeException不被认为是一个好的编程习惯? 处理RuntimeExceptions的正确方法是什么?

另外,为什么catch(Exception exc) {}没有捕获RuntimeException ? 这个行为是如何实现的?

通常, RuntimeException指示编程错误(在这种情况下,您无法“处理”它,因为如果您知道期望它,您已经避免了错误)。

捕获任何这些一般例外(包括Throwable )都是一个坏主意,因为这意味着你声称你了解每一个可能出错的情况,尽管如此,你仍然可以继续。 有时候在堆栈的顶层捕获Exception (但通常不是Throwable )是合适的,例如在Web服务器中 – 因为通常在单个请求出现问题时,您通常希望保持服务器启动并响应进一步的请求。 我通常不会捕获Throwable ,因为它包括Error子类,它通常用于表示真正的灾难性错误,通常最好通过终止进程来“处理”。

从根本上说,当出现错误时,你需要非常谨慎地继续执行某项任务 – 你需要对错误的含义有一个很好的了解,否则你可能会对世界状况做出错误的假设。 ,并使事情变得更糟。 在大多数情况下(并非所有情况),简单地放弃请求比尝试继续进行更好,无论神秘失败。 (它确实非常依赖于上下文 – 例如,在尝试获取一条辅助信息时,您可能并不关心出了什么问题。)

至于捕获Exception没有捕获RuntimeException – 这根本不是真的。 关于RuntimeException的唯一奇怪的事情是它(和子类)是未经检查的exception,而ExceptionException所有其他子类都被检查。

它归结为实际存在的不同类型的exception。

已检查的exception(即扩展Exceptionexception类)通常是您可以从中恢复的错误。

未经检查的exception(即显式扩展RuntimeExceptionexception类)是指示预期行为或程序状态中的错误的exception。 当然,当你取消引用对象的状态时,你不会得到NullPointerException

毯子捕捉一切 – 无论是Exception还是可Throwable ,这更糟糕 – 都不是一个好习惯,因为你假设你可以从任何特殊行为中恢复过来。 在某些情况下你不应该,或者实际上不能(即OutOfMemoryError for catch(Throwable t) )。 此外,捕获运行时exception表示代码异味; 这意味着你掩盖了编码错误。

明确你正在捕捉的是什么。

旁白:是的, catch Exception也会捕获RuntimeException ,因为ExceptionRuntimeException的超类。 同样, Throwable会捕获ExceptionError ,这就是写catch(Throwable t)

Throwable是所有Exception检查和未检查( RuntimeException )和错误的超类。

 java.lang.Object java.lang.Throwable java.lang.Exception java.lang.RuntimeException java.lang.Error 

理想情况下捕获错误不是一个好习惯。

并且由于RuntimeException扩展了Exception因此它捕获所有RuntimeExcption