是否应该检查并处理未经检查的exception?
我最近一直在阅读很多关于例外的post,我有一个问题是应该抓住未经检查的例外。 我已经读过,如果您希望应用程序从错误中恢复,请使用已检查的exception。 但是,如果您无法处理已检查的exception,则将其包装到另一个已检查的exception中,以便将其传递给另一个层; 例如,您包装SqlException
,或者抛出未经检查的exception。 但是,你应该捕获未经检查的exception吗? 未经检查的exception是理想的编程错误,您不检查? 它们应该从您的应用程序中冒出来吗?
是否应该检查并处理未经检查的exception?
答案是它取决于:
-
这取决于exception是什么。
-
这取决于抛出exception的原因。 它是“预期的”吗? 是由于错误,输入错误还是环境问题? 或者是其他东西?
-
这取决于是否有一个好的方法来恢复。 这通常部分取决于先前的标准。
如果exception是意外的,那么exception的原因是不确定的,并且/或者如果你没有捕获exception,如果没有声音恢复策略,那么通常最好允许exception冒泡,并确保它得到它报告/记录在顶层。
如果exception是Error
,则一般规则是您不应尝试恢复。 这包括StackOverflowError
和(特别是) OutOfMemoryError
。 Error
exception表示难以(或不可能)安全恢复的问题,最佳策略是允许或导致应用程序退出。
在顶级报告/记录是什么意思? 你的意思是在UI层捕获它并显示一个对话框,记录它等?
我的意思是应该将exception及其堆栈跟踪写入应用程序的日志文件,以便维护人员可以查看问题的证据。 您是否尝试向最终用户解释问题(以及如何解决)是一个单独的问题。
“顶级”可以是“主”方法,线程或可运行的“运行”方法……或未捕获的exception处理程序。 基本上它是exception最终将“冒泡”的地方,如果它没有被抓住。
您应该捕获exception – 已选中或未选中 – 如果您能够以有意义的方式处理它以从问题中恢复。 如果您没有好的方法来处理它,通常不应该捕获exception。
我已经看到太多代码通过执行e.printStackTrace()
来“处理”exception,然后继续,好像什么都没有错。 忽略这样的问题通常只会导致其他问题。
没有什么可以禁止你捕获运行时exception。
如今,趋势是使用越来越多的运行时exception,以及越来越少的已检查exception。 Spring,Hibernate和最新的Java EE规范几乎完全使用运行时exception。 这使得业务代码更易于阅读且不那么繁琐。
运行时exception通常不会被捕获,或者仅在UI层中的调用堆栈底部捕获,以显示错误消息,因为这通常是这样的exception时您可以做的唯一事情发生。
Checked
和Unchecked
Exception之间的基本区别在于,您需要显式处理前者或在inheritance hierarchy
传播它,而后者不需要这样做。
此外, CheckedException
从java.lang.Exception
扩展,而UncheckedExceptions
从java.lang.RuntimeException
扩展,不需要处理。 请注意, RuntimeException
本身是Exception
的子类。
鉴于上述所有信息,如果您handle
unchecked exception
则其罚款。 它会正常工作,控件将转到相应的catch
块。 但你不应该这样做。 除非,你真的需要它,你有一个正确的方法来处理它们。
-
例如: –您应该处理
IllegalArgumentException
,这是一个Unchecked Exception
。 -
然后,您不应该处理以下错误: –
StackOverflowError
。 因为,你不知道为什么会出现这个问题,以及什么是处理它的适当方法。 所以,将它留给JVM。Errors
Unchecked Exception
您无法从中恢复的Unchecked Exception
。
有关详细信息,请参阅以下链接: –
对于已检查exception的选择通常是:如果您无法对其执行任何操作,则只需将其添加到throws
如果您无法对其执行任何有用但可以添加信息,则将其catch
并转换为新原因作为原因并且如果可行的话, catch
它并做一些事情,并且在代码中做正确的事情。
未经检查的exception更棘手。 在理想的世界中,它们应该表明编程/逻辑错误,并且处理非常类似于断言失败,没有捕获,特别是不被吞噬。
来自Java标准库或其他库的一些未经检查的exception应该在我看来真的被检查exception,但不是。 在这些情况下,调用者应该承认这些exception可能会通过它们,即使它们没有catch
它们。 对于未经检查的exception,也可以检查exception,基本相同的规则:如果你想对它们做些什么,请抓住它们,否则让它们冒泡。 如果你正在创建一个库(即使它只是一个应用程序的内部),并且一个未经检查的exception确实应该在以后捕获,那么你可能想要捕获并重新将它包装到库代码中的一个已检查的exception中。
通常,尽量避免抛出未经检查的exception。 检查输入,所以你不需要catch
,如果仍然抛出exception,那么这是一个错误,应该保持未被捕获。 只有它是唯一或至少明显是最好的方式才能catch
它们。
为了公平对待Java库,这个语言是在那个时代设计的,当IDE还没有立即抱怨丢失抛出条款并提供自动填充它们时,所以通过减少开发人员的负担可以certificate它们未经检查。 但是使用现代工具,真的没有任何借口。
然后,正如其他答案中所提到的,有一些未经检查的例外,你不应该抓住。
你应该抓住未经检查的例外吗?
是和否取决于抛出的exception。
未经检查的exception是理想的编程错误,您不检查?
您可以编写一个catch
块来捕获未经检查的exception,但又取决于您是否应该这样做 。 如果你这样做,那么很可能一个bug在很长一段时间内仍未解决,当它被发现时它的大小也会发生变化。
它们应该从您的应用程序中冒出来吗?
如果它们发生,试着解决它们的原因(如果它可能的话)。 不要总是把它们当作硬和快的规则。