Java 何时可以接受抛出/捕获一般异常

Java 何时可以接受抛出/捕获一般异常,java,exception-handling,Java,Exception Handling,我继承的一个项目中有大量的try/catch块捕获了常规的异常。我一直在缓慢但肯定地重构它,但是有太多,以至于我一直在考虑在会议上把它作为一个问题提出来。这让我思考……是否真的有这样一种情况,即在生产环境中捕获一般异常是合理的?我想不出我需要抓住一般的例外情况,但我也是一个相当新的毕业生,我相信有很多我不知道。我做了一些研究,我可以找到很多不抓住一般例外的原因,但没有具体说明这种做法何时是合理的。显然,如果您正在调用一个已经抛出异常的方法,您必须捕获它。但是有没有一个原因可以让某些方法抛出异常,

我继承的一个项目中有大量的try/catch块捕获了常规的
异常。我一直在缓慢但肯定地重构它,但是有太多,以至于我一直在考虑在会议上把它作为一个问题提出来。这让我思考……是否真的有这样一种情况,即在生产环境中捕获一般异常是合理的?我想不出我需要抓住一般的例外情况,但我也是一个相当新的毕业生,我相信有很多我不知道。我做了一些研究,我可以找到很多不抓住一般例外的原因,但没有具体说明这种做法何时是合理的。显然,如果您正在调用一个已经抛出异常的方法,您必须捕获它。但是有没有一个原因可以让某些方法抛出
异常
,而不应该重构它来抛出特定的异常。

只有在需要抛出
异常
时才抛出
异常
。如果你抛出了一个过于笼统的异常,你实际上只是在喊“有问题”,而没有给出关于问题是什么的具体信息

仅当抛出异常时捕获异常,特别是。如果捕获的异常过于笼统,就失去了以正确方式处理特定异常的机会

抛出
异常
相当于返回
对象
,而不是对调用方有用的更具体的类型;捕获
异常
相当于将返回值分配给
对象
变量,而不是您可以使用的更具体的类型。基本上:您正在丢弃可用的类型信息

有时您必须抛出异常,因为您正在编写通用框架。例如,
Callable.call
抛出
异常
,因为您不知道将在那里执行什么代码,所以允许它抛出
异常
意味着您不约束类的用户。因此,如果要调用
可调用的
,则需要捕获
异常
;但你必须小心行事

绝大多数人没有(或不应该)编写框架,因此您不应该抛出或捕获
异常


在有效的Java中,第61项“抛出适合于抽象的异常”(这是第2版中的数字;不知道第3版)。基本上:您几乎肯定不想抛出
Exception
,但如果从文件读取的事实与您的API无关,您可能想抛出
IOException
,而不是
FileNotFoundException

只有在需要抛出
Exception
时才抛出
异常。如果你抛出了一个过于笼统的异常,你实际上只是在喊“有问题”,而没有给出关于问题是什么的具体信息

仅当抛出异常时捕获异常,特别是。如果捕获的异常过于笼统,就失去了以正确方式处理特定异常的机会

抛出
异常
相当于返回
对象
,而不是对调用方有用的更具体的类型;捕获
异常
相当于将返回值分配给
对象
变量,而不是您可以使用的更具体的类型。基本上:您正在丢弃可用的类型信息

有时您必须抛出异常,因为您正在编写通用框架。例如,
Callable.call
抛出
异常
,因为您不知道将在那里执行什么代码,所以允许它抛出
异常
意味着您不约束类的用户。因此,如果要调用
可调用的
,则需要捕获
异常
;但你必须小心行事

绝大多数人没有(或不应该)编写框架,因此您不应该抛出或捕获
异常


在有效的Java中,第61项“抛出适合于抽象的异常”(这是第2版中的数字;不知道第3版)。基本上:您几乎肯定不想抛出
Exception
,但如果从文件读取的事实与API无关,您可能希望抛出
IOException
,而不是
FileNotFoundException

捕获常规
异常不是最佳实践,因为,如果您正在捕获异常,您会告诉您可以处理该异常并从该异常状态恢复,但如果您无法恢复,那么失败可能比在非常不可预测的状态下继续工作要好

另一个可能发生的事情是捕获应该在更高级别上处理的异常,这可能再次导致危险状态

有可能代码是在引入多捕获时在Java7之前编写的,因此他们使用
Exception
而不是单独编写,或者开发人员对此不熟悉

至少在我看来,捕获
异常
是合理的唯一情况是在应用程序的顶部(
main
)-捕获所有未在较低级别处理的异常,记录它们并出于安全原因退出,然后很好地崩溃并向最终用户显示合理的消息

这就引出了另一件事,那就是抛出
异常
,与捕获一个你不应该抛出
异常
,这就像从每个方法返回对象一样,你失去了身份