原文 | dzone.com/articles/9-…

作者 | Thorben Janssen

翻译 | geekymv

无论你是初学者还是经验丰富的开发人员,对于你和你的团队来说,提高异常处理的能力可以更好的解决问题。

Java中的异常处理并不是一件容易的事,初学者会觉得很难理解,即使是经验丰富的开发人员也可能需要花费几个小时来讨论应该如何抛出或处理哪些异常。

这也是为什么大多数开发团队对于如何使用它们有自己的一套规则。如果你刚加入一个团队,你可能会惊讶这些规则与你之前使用过的规则是多么的不同。

尽管如此,依然有一些最佳实践在大多数团队中被使用。以下9个最重要的方法,可以帮助你开始或提高异常处理。

1、在 finally 代码块中清理资源或使用 try-with-resource 语句

你经常会在try代码块中使用一个资源,比如 InputStream,需要在之后关闭它。在这种情况下的一个常见错误是在try块的末尾关闭资源。

问题是,只要没有抛出异常这种方式可以很好的工作。try 代码块中的语句将被执行,并且资源将被关闭。

但是你添加 try 代码块是有原因的,你调用一个或多个可能抛出异常的方法,或者可能是你自己抛出异常,这意味着你可能未到达try代码块的尾部,最终,你无法关闭资源。

因此,你应该把所有清理代码放在 finally 代码块中,或者使用 try-with-resource 语句。

使用 finally 代码块

与 try 代码块最后几行不同,finally 代码块总是被执行。这种情况发生在 try 代码块成功执行之后,或者在catch 代码块中处理异常之后。因此,你可以确保清理了所有打开的资源。

Java7 中的 Try-With-Resource 语句

另一种方式是 try-with-resource 语句,我在介绍Java异常处理一文中有更详细的说明。

如果你的资源实现了 AutoCloseable 接口,就可以使用它。这是大多数 Java 标准资源所做的。当你在 try 子句中打开资源时,它将在try 代码块执行或者发生异常后自动关闭。

2、首选具体的异常

抛出的异常越具体越好。请记住,一个不知道你的代码的同事,也可能是几个月以后的你,需要调用你的方法并处理异常。

因此,确保提供给他们尽可能多的信息。这使你的API更容易理解。最终,方法的调用者将能够更好地处理异常或通过额外的检查来避免异常。

因此,总是试着找到最合适你的异常事件的类,例如,抛出 NumberFormatException 而不是 IllegalArgumentException。避免抛出一个不具体的异常。

3、为指定的异常编写文档

无论什么时候你在方法签名上指定一个异常时,你都应该在你的Javadoc中为其编写文档。这与之前的最佳实践有同样的目标:提供给调用者尽可能多的信息,以便他可以避免或者处理异常。

因此,确保在你的Javadoc中增加@throws 声明,并且描述可能造成异常的情况。

4、抛出带有描述性信息的异常

这个最佳实践背后的思想和之前两个类似,不同的是,你不用将信息提供给方法的调用者。每个需要了解记录在日志文件或监控工具中异常信息的人,都可以阅读该异常信息。

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

不要误会我的意思,你不应该写一个文本段落,而是应该用1-2两个短句解释异常的原因。这样可以帮助你的运维团队了解问题的严重性,也可以使你更容易分析任何服务事件。

如果抛出一个具体的异常,它的类名将最可能已经描述了错误的种类。因此,你不需要提供很多额外的信息。一个好的例子是 NumberFormatException。当你提供一个错误的字符串格式时,将由 java.lang.Long 类的构造方法抛出 NumberFormatException 异常。

NumberFormatException 类的名字已经告诉你问题的种类。它的信息仅仅需要提供导致问题的输入字符串。如果异常类的名字不那么具有表现力,则需要在消息中提供必要的信息。

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

译者注:可见,给类取个好名字多么重要。

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

大多数 IDE 都可以帮助你实现这个最佳实践。 当你尝试捕获不太具体的异常时,它们会报告一个不可到达的代码块。

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

总是首先捕获最具体的异常,然后将不太具体的 catch 代码块添加到列表的尾部。

在下面的代码片段中,你可以看到 try-catch 语句的例子,第一个 catch 代码块处理所有 NumberFormatException 异常,并且第二个 catch 代码块处理所有不属于 NumberFormatException 的 IllegalArgumentException 异常。

6、不要捕获 Throwable

Throwable 是所有 Exception 和 Error 类的父类。你可以在 catch 语句中使用它,但是你绝对不要这样做!

如果你在 catch 语句中使用 Throwable,它不仅捕获所有的 Exception,还将捕获所有的 Error。

Error 是被 JVM 抛出的,它表示不能被应用程序处理的严重问题。典型的例子是 OutOfMemoryError 或 StackOverflowError,都是由应用程序无法控制的情况引起的,并且无法处理。

因此,最好不要捕获 Throwable,除非你绝对确信自己处于能够或需要处理错误的特殊情况下。

7、不要忽略异常

你是否曾经分析过一个bug报告,其中只执行了用例的第一部分?

这通常是由忽略异常引起的,开发者可能很确信它从不会抛出,并且添加了不处理或不打印日志的 catch 代码块,当你找到这个代码块的时候,你甚至可能发现一个著名的注释“This will never happen”。

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

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

你至少应该写一条日志信息,告诉每个人意想不到的事情刚刚发生了,需要有人来检查它。

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、包装异常而不使用它

有时最好是捕获一个异常并将其包装到自定义异常中。这样异常的典型例子是应用程序或框架的具体业务异常。这使你可以增加额外的信息,并且还可以对异常类实现特殊处理。

当你这样做的时候,确保将原始异常设置为原因(cause)。Exception 类提供了接收 Throwable 参数的具体构造方法。否则,你会丢失堆栈跟踪和原始异常的信息,这将使分析导致异常的事件变得困难。

总结

如你所见,当你抛出或捕获异常的时候,你应该考虑很多不同的事情。它们中大多数的目标是提高代码的可读性或API的可用性。

异常通常是一种错误处理机制,同时也是一种通信机制。因此,你应该确保与你的同事讨论你想要应用的最佳实践和规则,以便每个人都理解一般的概念,并以相同的方式使用它们。

作者:Geek_ymv

链接:https://juejin.cn/post/6909838417278959630

来源:掘金

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

java添加异常处理_java异常处理措施相关推荐

  1. java 开发者异常处理_Java异常处理和设计

    本篇博客内容转自http://www.cnblogs.com/dolphin0520/p/3769804.html,内容供自己学习参考之用 在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序 ...

  2. java future 异常处理_Java异常处理总结

    转自:http://blog.51cto.com/lavasoft/18920 Java异常处理总结 异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if ...

  3. java批处理 异常处理_Java批处理教程

    java批处理 异常处理 在当今世界,互联网已经改变了我们的生活方式,其主要原因之一是大部分日常琐事都使用互联网. 这导致大量数据可用于处理. 其中涉及大量数据的一些示例是处理工资单,银行对帐单,利息 ...

  4. java 运行异常处理_Java编程异常处理和I/O流

    重点: 1.在编写程序时,要正确地使用捕获例外和声明抛出异常的两种例外处理的方法. 2.遇到实际问题时,要根据需要正确使用各种输入/输出流,特别是对中文使用适当的字符输入流. 3.正确使用对象串行化的 ...

  5. java添加信息_java – 向异常添加信息

    我想向堆栈跟踪/异常添加信息. 基本上我现在有这样的东西,我真的很喜欢: Exception in thread "main" java.lang.ArithmeticExcept ...

  6. java catch抛出异常_java异常——捕获异常+再次抛出异常与异常链

    [0]README 0.1) 本文描述+源代码均 转自 core java volume 1, 旨在理解 java异常--捕获异常+再次抛出异常与异常链 的相关知识: [1]捕获异常相关 1.1)如果 ...

  7. java exception子类_Java异常 Exception类及其子类(实例讲解)

    C语言时用if...else...来控制异常,Java语言所有的异常都可以用一个类来表示,不同类型的异常对应不同的子类异常,每个异常都对应一个异常类的对象. Java异常处理通过5个关键字try.ca ...

  8. java 是否继续_Java异常被抛出或被捕获之后,代码是否继续执行的问题

    在写程序的时候,我们经常被教导,要对异常的信息进行处理,哪里该抛出异常.但是,更多的时候,我们只是模仿异常的抛出,却不知道为什么要这样抛异常(被catch了?被向上抛了?后面的代码是否执行了?). 接 ...

  9. java添加坚挺_Java连载136-两种方式插入数据

    一.插入数据 对于数据的增删改查都有两种可选的操作模式,一种是直接使用SQL语句进行增删改查,另一种是通过可更新的结果集对象间接增删改查.首先创建语句对象 Statement stmt = con.c ...

  10. 22.Java之异常处理(异常介绍,异常体系图一览,运行时异常,编译异常,try-catch方式处理异常,throws异常处理,自定义异常,throws 和 throw 的区别)

    22.1.异常介绍 Java语言中,将程序执行中发生的不正常情况称为 "异常" (开发过程中的语法错误和逻辑错误不是异常) 执行过程中所发生的异常事件分为两大类: Error:Ja ...

最新文章

  1. CTF之一次曲折获取Flag的过程
  2. (一)vue 数据更新 试图不更新 解决办法
  3. linux命令:vim文件操作命令、新建用户,查看用户列表,chown命令
  4. qldump 备份所有表_MySQL中的备份和恢复是怎样执行的?
  5. springContext
  6. python转cpp_python转c工具
  7. python turtle画五边形_python画一朵玫瑰给你
  8. Oracle中用户和架构之间的区别?
  9. ros先订阅后发布 无法收到消息的解决办法
  10. datagrid--新增
  11. loadrunner具体实例教你如何进行结果分析
  12. 使用php建立评论系统
  13. xx闪购—主体选项卡
  14. ESP-8266wifi模块获取网络实时时间
  15. 不用 PLC与变频器通信程序 不用 三菱PLC与变频器通讯程序不经过 PLC与变频器通信
  16. kafka集群搭建(三台服务器)
  17. 2020年计算机设计大赛 人流量预测 (国赛三等奖)
  18. 前几天在头条上收到一条私信,内容大致是这样的:“我学校比较垃圾,想自学 Java 可以吗?自学 Java 难吗?毕业后能找到一份 6k左右的工作吗?”
  19. switch服务器帐户注销,堡垒之夜NS版Guest账号怎么更换_Guest账号退出更换方法介绍...
  20. 64位windows7,安装selenium2library成功后,无法在robotframework加载

热门文章

  1. mybatis-generator逆向工程生成boolean字段解决办法
  2. android ajax chrome,chrome浏览器ajax请求状态200,response为空的探索
  3. 清华大学电机学答案_电机学清华大学答案
  4. 关于cad2010的激活
  5. 山大824计算机基础,山大考研辅导班:山东大学2020年824计算机基础考研自命题科目考试大纲...
  6. java利用随机数简单发牌,!!!!!!!java新手求助,请教一个数组下标越界异常的问题...
  7. 单片机长按开关怎么控制_时控开关控制电铃怎么接线?
  8. 【洛谷P3804】统计每个子串出现的次数和长度(后缀自动机模版+拓扑序计数)
  9. 风控中英文术语手册(银行_消费金融信贷业务)_v4
  10. TensorFlow实践:经典CNN-AlexNet