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

时间:2014-06-21 18:18:52

标签: java exception-handling runtimeexception

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

另外,为什么catch(Exception exc) {}无法抓住RuntimeException?这种行为是如何实现的?

3 个答案:

答案 0 :(得分:17)

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

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

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

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

答案 1 :(得分:4)

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

已检查的异常(即扩展Exception的异常类)通常是恢复的错误。

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

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

明确关于你正在捕捉的内容。

除此之外:是的,catch Exception也会抓住RuntimeException,因为ExceptionRuntimeException的超类。同样,Throwable会抓住ExceptionError,这就是为什么写catch(Throwable t)会更糟。

答案 2 :(得分:2)

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

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

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

RuntimeException延伸Exception时,它会抓住所有RuntimeExcption