Java中异常处理的10个最佳实践

异常处理是书写强健JAVA应用的一个重要部分 。它是关乎每个应用的一个非功能性需求,是为了优雅的处理任何错误状况,比如资源不可访问,非法输入,空输入等等 。Java提供了几个异常处理特性,以try,catch和 finally 关键字的形式内建于语言自身之中 。Java编程语言也允许你创建新的异常,并通过使用 throw 和 throws关键字抛出它们 。事实上,异常处理不仅仅是知道语法 。书写一个强健的代码更多的是一门艺术而不仅仅是一门科学,这里我们将讨论一些关于异常处理的Java最佳实践 。这些 Java 最佳实践 甚至被标准JDK库,以及一些开源代码所追随,以更好的处理错误与异常 。这也成为了Java程序员书写强健代码的手册 。
Java 编程中异常处理的最佳实践
这里是我收集的10个Java编程中进行异常处理的10最佳实践 。在Java编程中对于检查异常有褒有贬,强制处理异常是一门语言的功能 。在本文中,我们将尽量减少使用检查型异常,同时学会在Java编程中使用检查型VS非检查型异常 。
【Java中异常处理的10个最佳实践】1.为可恢复的错误使用检查型异常,为编程错误使用非检查型错误
选择检查型还是非检查型异常,对于Java编程人员来说,总是让人感到困惑 。检查型异常保证你对错误条件提供异常处理代码,这是一种从语言到强制你编写健壮的代码的一种方式,但同时会引入大量杂乱的代码并导致其不可读 。当然,如果你有替代品和恢复策略的话,捕捉异常并做些什么看起来似乎也在理 。在Java编程中选择检查型异常还是运行时异常 。
2.在finally程序块中关闭或者释放资源
这在Java编程中,是一个广为人知的最佳实践,在处理网络和IO类的时候,相当于一个标准 。在finally块中关闭资源,在正常和异常执行的情况下,保证之前和稀缺资源的合理释放,这由y finally块保证 。从Java7开始,该语言有了一项更有趣的功能:资源管理自动化或者ARM块能实现这一功能 。尽管如此,我们仍然要记住在finally块中关闭资源,这是对于释放像FileDescriptors这类,应用在socket和文件编程的情况下的有限资源很重要的 。
3.在堆栈跟踪中包含引起异常的原因
很多时候,当一个由另一个异常导致的异常被抛出的时候,Java库和开放源代码会将一种异常包装成另一种异常 。日志记录和打印根异常就变得非常重要 。Java异常类提供了 getCause()方法来检索导致异常的原因,这些(原因)可以对异常的根层次的原因提供更多的信息 。该Java实践对在进行调试或排除故障大有帮助 。时刻记住,如果你将一个异常包装成另一种异常时,构造一个新异常要传递源异常 。
4.始终提供关于异常的有意义的完整的信息
异常信息是最重要的地方,因为这是程序员首先看到的第一个地方,这里你能找到问题产生的根本原因 。这里始终提供精确的真实的信息 。例如,对比IllegalArgumentException 异常的两条异常信息:
消息 1: "Incorrect argument for method"
消息 2: "Illegal value for ${argument}: ${value}
第一条消息仅说明了参数是非法的或者不正确,但第二条消息包括了参数名和非法值,而这对于找到错误的原因是很重要的 。在用Java编程中编写异常处理代码的时候,始终遵循该Java最佳实践 。
5.避免过度使用检查型异常
检查型异常在强制执行方面有一定的优势,但同时它也破坏了代码,通过掩盖业务逻辑使代码可读性降低 。只要你不过度使用检查型异常,你可以最大限度的减少这类情况,这样做的结果是你会得到更清洁的代码 。你同样可以使用Java7的新功能,像one catch block for multiple exceptions 和 automatic resource management以移除重复项 。
6.将检查型异常转为运行时异常
这是在像Spring之类的多数框架中用来限制使用检查型异常的技术之一,大部分出自于JDBC的检查型异常,都被包装进DataAccessException中,而(DataAccessException)异常是一种非检查型异常 。这是Java最佳实践带来的好处,特定的异常限制到特定的模块,像 SQLException 放到DAO层,将意思明确的运行时异常抛到客户层 。
7.记住对性能而言,异常代价高昂
需要记住的一件事是异常代价高昂,同时让你的代码运行缓慢 。假如你有方法从ResultSet(结果集)中进行读取,这时常会抛出SQLException异常而不会移到下一元素,这将会比不抛出异常的正常代码执行的慢的多 。因此最大限度的减少不必要的异常捕捉和移动,那里没有什么固定的原因 。不要仅仅是抛出和捕捉异常,如果你能使用boolean变量去表示执行结果,可能会得到更整洁,更高性能的解决方案 。修正错误的根源,避免不必须要的异常捕捉 。


推荐阅读