为啥捕获 RuntimeException 不被认为是一种好的编程习惯? [关闭]

Posted

技术标签:

【中文标题】为啥捕获 RuntimeException 不被认为是一种好的编程习惯? [关闭]【英文标题】:Why is catching a RuntimeException not considered a good programming practice? [closed]为什么捕获 RuntimeException 不被认为是一种好的编程习惯? [关闭] 【发布时间】:2014-08-12 05:30:14 【问题描述】:

为什么使用catch(Throwable exc) 捕获RuntimeException 不是一种好的编程习惯?处理 RuntimeExceptions 的正确方法是什么?

另外,为什么catch(Exception exc) 没有捕捉到RuntimeException?这种行为是如何实现的?

【问题讨论】:

catch 确实捕获了RuntimeException 因为未经检查的异常通常是可以通过使用if 语句执行简单检查来避免的异常。 IE。使用if(myObject != null) 可以避免NullPointerException。此外,iftry-catch 快。真正需要时使用try-catch 我不同意捕获 RuntimeException 是不好的做法。捕获然后忽略错误......这很糟糕。 【参考方案1】:

归结为实际存在的不同类型的异常。

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

未经检查的异常(即显式扩展RuntimeException 的异常类)是那些在预期行为或程序状态中指示错误的异常。当然,如果在取消引用时对象的状态不是 null,您将不会得到 NullPointerException

抓住毯子一切 - ExceptionThrowable,这更糟糕 - 不是一个好习惯,因为你'假设您可以从任何异常行为中恢复。在某些情况下,您不应该或实际上不能(例如,OutOfMemoryError 代表 catch(Throwable t))。此外,捕获运行时异常表明代码异味。这意味着您正在掩盖一个编码错误。

明确说明你正在捕捉什么。

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

【讨论】:

“明确说明你正在捕捉什么。”为什么呢?我不认为这是一个好的编程建议。如果您正在对一个类进行建模并且您希望它永远不会传播异常,那么捕获所有Exceptions 是非常好的。 (我同意捕获 Throwable 不好)。【参考方案2】:

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

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

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

由于RuntimeException 扩展了Exception,所以它捕获了所有RuntimeExcption

【讨论】:

【参考方案3】:

通常,RuntimeException 表示编程错误(在这种情况下,您无法“处理”它,因为如果您知道会发生这种情况,您就可以避免该错误)。

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

从根本上说,当出现错误时,您需要非常谨慎地继续执行特定任务 - 您需要对错误的含义有一个很好的了解,否则您可能会继续错误地假设状态世界,并使事情变得更糟。在大多数 情况下(不是全部),简单地放弃请求比尝试继续进行而不考虑神秘的失败要好。 (不过,这在很大程度上取决于上下文 - 例如,在尝试获取一条辅助信息时,您可能不在乎出了什么问题。)

至于捕捉Exception 不捕捉RuntimeException - 这根本不是真的。 RuntimeException 唯一奇怪的是它(和子类)是未经检查的异常,而 ExceptionException 的所有其他子类都是经过检查的。

【讨论】:

....您好,您能否详细说明检查和未检查异常的行为方式有何不同? @SumitPalSingh:已经有很多好的信息可用。阅读 Java 教程:docs.oracle.com/javase/tutorial/essential/exceptions/index.html

以上是关于为啥捕获 RuntimeException 不被认为是一种好的编程习惯? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在这个多线程示例中没有捕获到异常?

如何解释Exception是不是会捕获RuntimeException?

未捕获的异常“RuntimeException”,消息“无法写入缓存目录”

Java -- 异常的捕获及处理 -- Exception类与RuntimeException类

runtimeException也是能够捕获的

Laravel 7致命错误:未捕获的RuntimeException:尚未设置外观根