多年来,我一直无法得到以下问题的一个像样的答案:为什么一些开发人员如此反对受控异常?我有过无数次的对话,在博客上读过一些东西,读过Bruce Eckel说的话(我看到的第一个站出来反对他们的人)。
我目前正在编写一些新代码,并非常注意如何处理异常。我正试图从“我们不喜欢有限制的例外”的观点出发。人群拥挤,我仍然看不到它。
我的每一次谈话都以同样的问题结束。让我把它建立起来:
一般来说(从Java的设计方式来看),
Error
是不应该被抓到的东西(VM有花生过敏,有人掉了一罐花生在上面)RuntimeException
是程序员做错的事情(程序员离开数组的末尾)Exception
(除了RuntimeException
)是用于程序员无法控制的事情(磁盘在写入文件系统时被填满,进程的文件句柄限制已经达到,你不能再打开任何文件)Throwable
只是所有异常类型的父类。我听到的一个常见的说法是,如果发生了异常,那么所有开发人员要做的就是退出程序。
我听到的另一个常见论点是受控异常使得重构代码更加困难。
因为“我要做的就是退出”;我认为即使你正在退出,你也需要显示一个合理的错误信息。如果你只是在处理错误上押注,那么当程序在没有明确说明原因的情况下退出时,你的用户不会太高兴。
因为“它使重构变得困难”;这说明没有选择正确的抽象层次。与其声明方法抛出IOException
,不如将IOException
转换为更适合当前情况的异常。
我对用catch(Exception)
(或在某些情况下catch(Throwable)
包装Main没有问题,以确保程序可以优雅地退出-但我总是捕获我需要的特定异常。这样做至少可以显示适当的错误消息。
人们从来不会回答的问题是:
如果你抛出
RuntimeException
而不是Exception
子类,你怎么知道 你应该去抓?< / p >
如果答案是catch Exception
,那么你也在以与系统异常相同的方式处理程序员错误。在我看来这是不对的。
如果你捕获了Throwable
,那么你正在以同样的方式处理系统异常和虚拟机错误(等等)。在我看来这是不对的。
如果答案是您只捕获您知道抛出的异常,那么您如何知道抛出了哪些异常呢?当程序员X抛出一个新的异常而忘记捕获它时会发生什么?这对我来说似乎很危险。
我认为显示堆栈跟踪的程序是错误的。不喜欢受控异常的人不会有这种感觉吗?
所以,如果你不喜欢受控异常,你能解释一下为什么不,并回答没有得到回答的问题吗?
我不是在寻找关于何时使用这两种模型的建议,我在寻找的是为什么人们从RuntimeException
扩展,因为他们不喜欢从Exception
扩展和/或为什么他们捕捉到异常,然后重新抛出RuntimeException
,而不是向他们的方法添加抛出。我想了解不喜欢受控异常的动机。