Java Exceptions,要捕获什么以及不应该捕获什么?

Kev*_*oyd 7 java exception

我在运行我的Java应用程序时不断遇到可怕的java.something.someException错误.而且我似乎没有掌握什么例外处理和什么不处理?
当我阅读api文档时,大多数函数抛出异常,就像我使用I/O或使用数组......等.

如何根据什么参数决定捕获哪些异常以及哪些异常捕获?

我在这里谈论检查的例外情况.

Mik*_*oss 15

简短的回答

捕捉当时和那里可以处理的异常,重新抛出你不能做的事情.

答案很长

它被称为异常处理代码的原因是:每当你想要编写一个catch块时,你需要有一个很好的理由来捕获异常.一个catch块表明你捕获异常的意图,然后对它做一些事情.做某事的例子包括但不限于:

  • 重试抛出异常的操作.IOException对于可能是临时的(以及在尝试将文件上传到服务器时出现网络错误)的情况,这可能是有意义的.也许您的代码应该重试上载几次).

  • 记录异常.是的,记录就像做某事一样.您可能还希望在记录之后重新抛出原始异常,以便其他代码仍有机会处理异常,但这取决于具体情况.

  • 将异常包装在另一个更适合您的类接口的异常中.例如,如果你有一个FileUploader类,你可以IOException用更通用的方式包装,UploadFailedException这样使用你的类的类就不必详细了解你的上传代码是如何工作的(事实上它抛出一个IOException技术上是一个实现细节) ).

如果代码在发生问题时无法合理地解决问题,那么你根本就不应该抓住它.

不幸的是,这种严格的规则永远不会在100%的时间内发挥作用.有时,您使用的第三方库会抛出您真正不关心的或者实际上永远不会发生的已检查异常.在这些情况下,您可以使用catch不运行任何代码的空块,但这不是推荐的处理异常的方法.至少,你应该添加一个注释来解释为什么你忽略了异常(但正如CPerkins在评论中指出的那样,"永远不要说永远不会".)你可能想要实际记录这些"永远不会发生"的事情.异常,所以如果发生这种异常,你就会意识到这一点,并可以进一步调查).

但是,一般规则是,如果您所处的方法无法通过异常(记录它,重新抛出它,重试操作等)做一些合理的事情,那么您根本不应该写一个catch块.让调用方法处理异常.如果您正在处理已检查的异常,请将已检查的异常添加到throws方法的子句中,该子句告诉编译器将异常向上传递给调用方法,这可能更适合处理错误(调用方法可能有更多上下文,所以它可能更好地了解如何处理异常).

通常,最好try...catch在您的main方法中放入一个,它将捕获您的代码无法处理的任何异常,并将此信息报告给用户并优雅地退出应用程序.

最后,别忘了 finally

另外请记住,即使您没有编写块,如果您需要清理代码来运行,无论您尝试执行的操作是否抛出异常catch,您仍可能需要编写一个finally块.一个常见的例子是在try块中打开一个文件:即使发生异常,您仍然希望关闭该文件,即使您的方法不会捕获异常.实际上,您可能会在教程和书籍中看到的另一个常见的经验法则是,try...finally块应该更常见try...catch于代码中的块,正是因为catch块只应在实际处理异常时写入,但finally每当您需要块时代码需要自己清理.


Jim*_*ans 5

我强烈推荐Joshua Bloch的Effective Java,第2版中的第9章(例外)来解决这些问题.