有关于异常捕获点滴,plus我也揭揭apache-common ExceptionUtils的短

简介: 本文通过示例展示了Java编程中异常处理的几种不当做法,包括无意义地捕获并重新抛出异常、改变异常堆栈信息以及私自“吞噬”异常等,并指出了这些做法可能带来的问题,如增加排障难度等。同时,文章推荐了在捕获异常后打印错误日志的良好习惯,并介绍了如何使用`try...finally`结构进行资源管理和程序状态记录。此外,还特别提到了Apache Commons Lang库中的`ExceptionUtils`工具类在记录异常堆栈信息方面的应用价值,但也对其某些行为提出了疑问,鼓励读者深入探究。

先如下代码:

1    @Test

2     public void testException1() {

3         System.out.println("begin...");

4         int[] arr = new int[]{1};

5         System.out.println(arr[1]);

6     }

如下是运行结果,异常是从第5行抛出来的,控制台里显示的异常堆栈信息也是始于第5行。

java.lang.ArrayIndexOutOfBoundsException: 1
    at com.mytest.testException1(MyExceptionTest.java:5)


我们在写程序时往往要捕获异常。如下是画蛇添足型:

1    @Test

2     public void testException() {

3         try {

4             System.out.println("begin...");

5             int[] arr = new int[]{1};

6             System.out.println(arr[1]);

7         } catch (Exception ex) {

8             throw ex;

9        }

10     }

很明显,捕获了异常,却只是原样throw出去,没任何意义!


如下处理方式也不可取:

1    @Test

2     public void testException() {

3         try {

4             System.out.println("begin...");

5             int[] arr = new int[]{1};

6             System.out.println(arr[1]);

7         } catch (Exception ex) {

8             throw new MyException( ex.getMessage() );

9        }

10     }

 

异常的堆栈始于抛出异常的代码行。catch里经过这样中转后,导致堆栈信息的显示的行号不再是6,而是8。尤其当代码逻辑复杂时,这样做无疑增加了排障的难度。

当然,我们有时要在系统里通过自定义异常类型,来实现我们所需的逻辑控制(自定义异常是个好东西哦,《代码整洁之道》一书中多次提到使用异常来替代错误码)。如果真要通过MyExecption中转出去,可在throw之前将完整的异常信息记录到日志文件里。

catch里捕获到Exception后,先打印error log再做后续处理,会是个好习惯。


私自吞异常是要犯法的哦~~

类似如下代码是不是很熟悉?哈哈,去翻翻自己写的代码吧~

1     public int myBiz() {

2         int result;

3         try {

4             System.out.println("begin...");

5             int[] arr = new int[]{1};

6             result = arr[1];

7             return result;

8         } catch (Exception e) {

9             return 0;

10        }

11     }

 

有时,我们要借助try...finally

finally里的代码会在try子句或catch子句执行完成后执行。借助try...finally,我们可以设置日志埋点,比如:记录程序耗时,记录程序完结标记。也可以用来释放资源,例如:关闭IO、释放流。

1     public void testTryFinally() {

2         try {

3             System.out.println("begin...");

4             int[] arr = new int[]{1};

5             System.out.println(arr[1]);

6         }finally {

7             System.out.println("over");

8        }

9     }

 

利用ExceptionUtils记录异常

当程序运行过程中出现异常时,将异常的详细信息打印到日志文件是必不可少的,这将有助于我们排障。

.net程序员都知道,要打印出来一个异常的详细信息,直接ex.ToString()就可以了。

如果在java里,你还这样,那就out了。查看一下Exception的基类——Throwable的toString()方法,可知,ex.toString()返回的是异常类型和message。

这时,要打印完整的异常信息,apache commons-lang3包里的ExceptionUtils工具类可要派上用场了。 没错,用ExceptionUtils#getStackTrace(final Throwable throwable)

揭短ExceptionUtils

有些异常并没有root cause的,此时,调用ExceptionUtils的getRootCause(final Throwable throwable)返回值是null,而你调用其getRootCauseMessage(final Throwable th)时,反而有返回值。 查看getRootCauseMessage的代码实现,发现它做了二元判断,如果root cause是null,它就去取th本身的message。 前者返回null,后者有返回值,自我赶脚有些费解!what about you?

//public class ExceptionUtils {
public static Throwable getRootCause(final Throwable throwable) {
    final List<Throwable> list = getThrowableList(throwable);
    return list.size() < 2 ? null : (Throwable)list.get(list.size() - 1);
}
public static String getRootCauseMessage(final Throwable th) {
    Throwable root = ExceptionUtils.getRootCause(th);
    root = root == null ? th : root;
    return getMessage(root);
}

 

目录
相关文章
|
XML JSON 算法
Duang!Duang!Duang!直击痛点的一款 HTTP 客户端框架(Java),墙裂推荐!(2)
Duang!Duang!Duang!直击痛点的一款 HTTP 客户端框架(Java),墙裂推荐!
339 0
|
6月前
|
搜索推荐
代码分享|GPL平台没有基因注释什么办?别慌,基因ID注释万能公式!
本文介绍了处理无基因注释的GEO数据集的方法。当遇到GPL平台无基因注释时,可以通过以下步骤解决:1) 查看数据集补充文件中是否已有注释矩阵;2) 使用搜索引擎或官网查找相关资源;3) 如数据集较新,尝试联系平台官方;4) 利用已有经验进行转换。文中通过多个GSE示例详细解释了如何处理不同情况,并提醒读者注意检查数据集中可能隐藏的注释信息。作者提供了转换ID的代码,并在公众号“多线程核糖体”分享了相关资源。
585 0
|
Java BI 数据库
特别诺贝尔奖论文《天赋与运气:随机性在成功与失败中的作用》代码实现简版(JAVA)
特别诺贝尔奖论文《天赋与运气:随机性在成功与失败中的作用》代码实现简版(JAVA)
|
Java 调度 数据库
坑爹!Quartz 重复调度问题,你遇到过么?(2)
坑爹!Quartz 重复调度问题,你遇到过么?
234 0
坑爹!Quartz 重复调度问题,你遇到过么?(2)
|
存储 安全 Java
坑爹!Quartz 重复调度问题,你遇到过么?(1)
坑爹!Quartz 重复调度问题,你遇到过么?
341 0
坑爹!Quartz 重复调度问题,你遇到过么?(1)
|
安全 Java 数据库连接
麻了,代码改成多线程,竟有9大问题 下
麻了,代码改成多线程,竟有9大问题 下
|
消息中间件 JavaScript 小程序
麻了,代码改成多线程,竟有9大问题 上
麻了,代码改成多线程,竟有9大问题 上
【perl】老司机的再一次翻车:没有想到加了一句打印,会影响结果输出
【perl】老司机的再一次翻车:没有想到加了一句打印,会影响结果输出
|
Java 数据库连接
你有没有掉进去过这些 Exception 的“陷阱“(Part C)
你有没有掉进去过这些 Exception 的“陷阱“(Part C)
你有没有掉进去过这些 Exception 的“陷阱“(Part C)
|
Java API 容器
你有没有掉进去过这些 Exception 的“陷阱“(Part B)
你有没有掉进去过这些 Exception 的“陷阱“(Part B)
你有没有掉进去过这些 Exception 的“陷阱“(Part B)