我继承的其中一个项目充斥着大量的try / catch块来捕捉普通Exception
。我已经慢慢但肯定地重构了这一点,但是有很多,所以我一直在考虑把它作为一个关注在会议中。这让我开始思考......是否真的存在这样的情况:在生产环境中捕获一般异常是合理的?我想不出一个我需要抓住一般例外情况的案例,但我也是一个相当近期的毕业生,我确信我不知道有多少吨。我做了一些研究,我可以找到很多理由,为什么不抓住一般的例外,但没有具体的说明这种做法是否合理。显然,如果您正在调用已抛出异常的方法,则必须捕获它。但有没有理由某个方法可以抛出Exception
并且不应该重构它来抛出特定的异常。?
答案 0 :(得分:2)
如果您需要抛出Exception
,请仅投掷Exception
。如果你抛出过于笼统的异常,你实际上只是在喊“有问题”,而没有提供有关该问题的具体信息。
如果引发Exception
,则仅捕获Exception
。具体而言。如果你抓住过于笼统的例外,你将失去以正确的方式处理特定异常的机会。
投掷Exception
相当于返回Object
而不是更具体的类型,这对调用者有用;捕获Exception
相当于为Object
变量赋予返回值,而不是您可以使用的更具体的类型。基本上:您正在丢弃可用的类型信息。
有时你必须抛出Exception
,因为你正在编写一个通用框架。例如,Callable.call
抛出Exception
,因为您不知道将在那里执行哪些代码,因此允许它抛出Exception
意味着您不会限制该类的用户。因此,如果您拨打Callable
,则需要抓住Exception
;但你需要小心谨慎。
绝大多数人都没有(或不应该)编写框架,所以你不应该抛弃或捕捉Exception
。
在 Effective Java ,第61项,“抛出适合抽象的例外”这方面有很好的建议(这是第二版中的数字;不知道第三版)。基本上:你几乎肯定不想抛出Exception
,但你可能想要抛出IOException
而不是FileNotFoundException
,如果你正在从文件中读取这一事实与您的API无关。
答案 1 :(得分:1)
捕获常规Exception
不是最佳做法,因为如果您捕获异常,则告诉您可以处理它并从该异常状态恢复,但如果您无法恢复,则可能更好失败而不是继续处于非常不可预测的状态。
可能发生的另一件事是捕获应该在更高级别处理的异常,这可能再次导致危险状态。
当引入multi-catch时,有可能在Java 7之前编写代码,因此他们使用Exception
而不是单独编写每个代码,或者开发人员不熟悉它。
只有在我看来,捕获Exception
是合理的情况才是合理的,在应用程序的顶部(main
) - 捕获所有未在较低级别处理的异常,记录它们和出于安全原因退出,并且很好地崩溃并向最终用户显示合理的信息。
这给我们带来了另一件事,那就是抛出Exception
,就像抓住一个你不应该抛出Exception
一样,就像从每个方法中返回Object一样,你失去了身份。
如果这两件事在你正在研究的项目中非常普遍,也许你应该考虑向高级开发人员提及。