Java 异常处理的 9 个最佳实践

原文地址:https://dzone.com/articles/9-...

翻译出处:https://www.oschina.net/trans...

在 Java 中,异常处理是个很麻烦的事情。初学者觉得它很难理解,甚至是经验丰富的开发者也要花费很长时间决定异常是要处理掉和抛出。

所以很多开发团队约定一些原则处理异常。如果你是一个团队的新成员,你可能会很惊讶,因为他们约定的规则可能和你以前使用的规则不一样。

不过,有很多最佳实践的规则,被大部分团队接受。这里有 9 大重要的约定,帮助你学习或者改进异常处理。

1、在 Finally 清理资源或者使用 Try-With-Resource 特性

大部分情况下,在 try 代码块中使用资源后需要关闭资源,例如 InputStream 。在这些情况下,一种常见的失误就是在 try 代码块的最后关闭资源。

问题就是,只有没有异常抛出的时候,这段代码才可以正常工作。try 代码块内代码会正常执行,并且资源可以正常关闭。但是,使用 try 代码块是有原因的,一般调用一个或多个可能抛出异常的方法,而且,你自己也可能会抛出一个异常,这意味着代码可能不会执行到 try 代码块的最后部分。结果就是,你并没有关闭资源。

所以,你应该把清理工作的代码放到 finally 里去,或者使用 try-with-resource 特性。

使用 Finally 代码块
与前面几行 try 代码块不同,finally 代码块总是会被执行。不管 try 代码块成功执行之后还是你在 catch 代码块中处理完异常后都会执行。因此,你可以确保你清理了所有打开的资源。

Java 7 的 Try-With-Resource 语法
另一个可选的方案是 try-with-resource 语法,我在介绍 Java 的异常处理里更详细的介绍了它。

如果你的资源实现了 AutoCloseable 接口,你可以使用这个语法。大多数的 Java 标准资源都继承了这个接口。当你在 try 子句中打开资源,资源会在 try 代码块执行后或异常处理后自动关闭。

2、优先明确异常

你抛出的异常越明确越好,永远记住,你的同事或者几个月之后的你,将会调用你的方法并且处理异常。

因此需要保证提供给他们尽可能多的信息。这样你的 API 更容易被理解。你的方法的调用者能够更好的处理异常并且避免额外的检查。

因此,总是尝试寻找最适合你的异常事件的类,例如,抛出一个 NumberFormatException 来替换一个 IllegalArgumentException 。避免抛出一个不明确的异常。

3、记录指定的异常

每当你在方法签名中指定异常,你也应该在 Javadoc 中记录它。 这与上一个最佳实践具有相同的目标:尽可能多地向调用者提供信息,以便避免或处理异常。

因此,请确保向 Javadoc 添加 @throws 声明并描述可能导致异常的情况。

4、使用描述性消息抛出异常

这个最佳实践背后的想法与前两个类似。但这一次,你不会将信息提供给方法的调用者。每个必须了解在日志文件或监视工具中报告异常情况时发生了什么情况的人都可以读取异常消息。

因此,应该尽可能精确地描述问题,并提供最相关的信息来了解异常事件。

不要误会我的意思,你不用去写一段文字。但你也应该在1-2个短句中解释异常的原因。这有助于你的运营团队了解问题的严重性,并且还可以让你更轻松地分析任何服务突发事件。

如果抛出一个特定的异常,它的类名很可能已经描述了这种错误。所以,你不需要提供很多额外的信息。一个很好的例子是 NumberFormatException 。当你以错误的格式提供 String 时,它将被 java.lang.Long 类的构造函数抛出。

NumberFormatException 类的名称已经告诉你这种问题。它的消息表示只需要提供导致问题的输入字符串。如果异常类的名称不具有表达性,则需要在消息中提供所需的信息。

17:17:26,386 ERROR TestExceptionHandling:52 - java.lang.NumberFormatException: For input string: "xyz"

5、优先捕获最具体的异常

大多数 IDE 都可以帮助你实现这个最佳实践。当你尝试首先捕获较不具体的异常时,它们会报告无法访问的代码块。

但问题在于,只有匹配异常的第一个 catch 块会被执行。 因此,如果首先捕获 IllegalArgumentException ,则永远不会到达应该处理更具体的 NumberFormatException 的 catch 块,因为它是 IllegalArgumentException 的子类。

总是优先捕获最具体的异常类,并将不太具体的 catch 块添加到列表的末尾。

你可以在下面的代码片断中看到这样一个 try-catch 语句的例子。 第一个 catch 块处理所有 NumberFormatException 异常,第二个处理所有非 NumberFormatException 异常的 IllegalArgumentException 异常。

6、不要捕获 Throwable 类

Throwable 是所有异常和错误的超类。你可以在 catch 子句中使用它,但是你永远不应该这样做!

如果在 catch 子句中使用 Throwable ,它不仅会捕获所有异常,也将捕获所有的错误。JVM 抛出错误,指出不应该由应用程序处理的严重问题。 典型的例子是 OutOfMemoryError 或者 StackOverflowError 。 两者都是由应用程序控制之外的情况引起的,无法处理。

所以,最好不要捕获 Throwable ,除非你确定自己处于一种特殊的情况下能够处理错误。

7、不要忽略异常

你曾经有去分析过一个只执行了你用例的第一部分的 bug 报告吗?

这通常是由于一个被忽略的异常造成的。开发者可能会非常肯定,它永远不会被抛出,并添加一个 catch 块,不做处理或不记录它。而当你发现这个块时,你很可能甚至会发现其中有一个“这永远不会发生”的注释。

那么,你可能正在分析一个不可能发生的问题。

所以,请不要忽略任何一个异常。 你不知道代码将来如何改变。有人可能会在没有意识到会造成问题的情况下,删除阻止异常事件的验证。或者是抛出异常的代码被改变,现在抛出同一个类的多个异常,而调用的代码并不能阻止所有异常。

你至少应该写一条日志信息,告诉大家这个不可思议的事发生了,而且有人需要检查它。

8、不要记录日志和抛出错误

这可能是该文章中最常被忽略的最佳实践。 你可以找到很多的其中有一个异常被捕获的代码片段,甚至是一些代码库,被记录和重新抛出。

在发生异常时记录异常可能会感觉很直观,然后重新抛出异常,以便调用者可以适当地处理异常。但它会为同一个异常重复写入多个错误消息。

17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException: For input string: "xyz"
Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:589)
at java.lang.Long.(Long.java:965)
at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)
at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)
附加消息也不会添加任何信息。正如在最佳实践#4中所解释的那样,异常消息应该描述异常事件。 堆栈跟踪告诉你在哪个类,方法和行中抛出异常。

如果你需要添加其他信息,则应该捕获异常并将其包装在自定义的信息中。 但请务必遵循最佳实践9。

所以,只捕获你想处理的异常。 否则,在方法签名中指定它,并让调用者处理它。

9、封装好的异常类而不使用

有时候,最好是捕获一个标准异常并将其封装成一定制的异常。一个典型的例子是应用程序或框架特定的业务异常。允许你添加些额外的信息,并且你也可以为你的异常类实现一个特殊的处理。

在你这样做时,请确保将原始异常设置为原因(注:参考下方代码 NumberFormatException e 中的原始异常 e )。Exception 类提供了特殊的构造函数方法,它接受一个 Throwable 作为参数。另外,你将会丢失堆栈跟踪和原始异常的消息,这将会使分析导致异常的异常事件变得困难。

总结
如你所见,当你抛出或捕获异常的时候,有很多不同的事情需要考虑,而且大部分事情都是为了改善代码的可读性或者 API 的可用性。

异常通常都是一种异常处理技巧,同时也是一种通信媒介。因此,为了和同事更好的合作,一个团队必须要制定出一个最佳实践和规则,只有这样团队成员才能理解这些通用概念,同时在工作中使用它。

Java 异常处理的 9 个最佳实践相关推荐

  1. 《转载》Java异常处理的10个最佳实践

    本文转载自 ImportNew - 挖坑的张师傅 异常处理在编写健壮的 Java 应用中扮演着非常重要的角色.异常处理并不是功能性需求,它需要优雅地处理任何错误情况,比如资源不可用.非法的输入.nul ...

  2. 关于JAVA异常处理的20个最佳实践

    关于JAVA异常处理的20个最佳实践 在我们深入了解异常处理最佳实践的深层概念之前,让我们从一个最重要的概念开始,那就是理解在JAVA中有三种一般类型的可抛类: 检查性异常(checked excep ...

  3. 小菜:Java异常处理的10个最佳实践

    转载自   小菜:Java异常处理的10个最佳实践 异常处理在编写健壮的 Java 应用中扮演着非常重要的角色.异常处理并不是功能性需求,它需要优雅地处理任何错误情况,比如资源不可用.非法的输入.nu ...

  4. Java 异常处理的 9 个最佳实践 1

    点击蓝色"程序猿DD"关注我哟 加个"星标",不忘签到哦 来源:开源中国 在 Java 中,异常处理是个很麻烦的事情.初学者觉得它很难理解,甚至是经验丰富的开发 ...

  5. java 异常 最佳实践_关于JAVA异常处理的20个最佳实践

    在我们深入了解异常处理最佳实践的深层概念之前,让我们从一个最重要的概念开始,那就是理解在JAVA中有三种一般类型的可抛类: 检查性异常(checked exceptions).非检查性异常(unche ...

  6. Java 异常处理的 20 个最佳实践,你知道几个?| CSDN 博文精选

    作者 | 武培轩 责编 | 屠敏 出品 | CSDN 博客 异常处理是 Java 开发中的一个重要部分,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等.Java 提供了几个异常处理特性 ...

  7. Java 中处理 Exception 的最佳实践

    Java 中处理 Exception 的最佳实践 在Java中处理异常并不是一个简单的事情.不仅仅初学者很难理解,即使一些有经验的开发者也需要花费很多时间来思考如何处理异常,包括需要处理哪些异常,怎样 ...

  8. JAVA应用开发MQ实战最佳实践——Series2:消息队列RocketMQ性能测试案例

    简介:JAVA应用开发MQ实战最佳实践--Series2:消息队列RocketMQ性能测试案例 往期内容 JAVA应用开发MQ实战最佳实践--Series1:RocketMQ综述及代码设计 1. 消息 ...

  9. java 异常 最佳实践_处理Java异常的10种最佳实践

    java 异常 最佳实践 在本文中,我们将看到处理Java异常的最佳实践. 用Java处理异常不是一件容易的事,因为新手很难理解,甚至专业的开发人员也可能浪费时间讨论应该抛出或处理哪些Java异常. ...

最新文章

  1. 虚拟机网络连接方式linuxcentos
  2. 找到二叉树中符合搜索二叉树条件的最大拓扑结构
  3. TypeScript里的空值合并运算符(双问号)用法
  4. ASP.NET程序中常用的三十三种代码(二)
  5. 设计灵感|App中的页面空状态应该如何表现?
  6. 以太坊2.0合约余额新增2.62万ETH
  7. 「代码随想录」322. 零钱兑换 【动态规划】力扣详解!
  8. Ardunio开发实例-AM2320温湿度传感器
  9. 服务器运行一天死机,服务器死机怎么办?教你排除故障
  10. 计算机毕业设计Python+Django的医院排队叫号系统(源码+系统+mysql数据库+Lw文档)
  11. 关于win10系统安装了DirextX组件,游戏里却没有声音的解决方法
  12. 延迟发送:4款定时发送短信的应用程序
  13. 技术太多学不过来?教你如何越学越带劲
  14. 怎么查看电脑内存的型号
  15. anaconda3 复制or克隆环境
  16. 蓝牙助手android,蓝牙助手手机版
  17. 4.9. 相等的多项式
  18. 手把手教你炫酷慕课网视频启动导航的完美实现
  19. lol登入服务器显示证书,登录LOL提示安全证书不可用怎么办
  20. 英国电信收入大增 收购EE效应初步显现

热门文章

  1. Netty:Java 领域网络编程的王者
  2. 理解 Linux 的虚拟内存
  3. 求求你别再写上千行的类了,试试这些牛逼的重构技巧吧
  4. 你说,一个Java字符串到底有多少个字符?
  5. Spring Cloud第十四篇: 服务注册(consul)
  6. 机器学习调参自动优化方法
  7. 王茂霖:数据挖掘提分三板斧!
  8. 一文读懂深度学习中的各种卷积
  9. Hinton等6位图灵奖得主、百余位顶级学者邀你加入群聊,共话人工智能下一个十年...
  10. Google 确认 Chrome 存在严重漏洞,向 20 亿用户发出警告:你们需立即更新浏览器...