▄︻┻┳═一『异常捕获系列』Agenda:

▄︻┻┳═一有关于异常捕获点滴,plus我也揭揭java的短

▄︻┻┳═一根据异常自定义处理逻辑(【附】java异常处理规范)

▄︻┻┳═一利用自定义异常来重构代码


先如下代码:

     @Test
public void testException1() {
System.out.println("begin...");
int[] arr = new int[]{1};
System.out.println(arr[1]);
}

执行结果:

java.lang.ArrayIndexOutOfBoundsException: 1

	at com.emax.paycenter.web.controller.PayCenterAgentPayAPITest.testException1(PayCenterAgentPayAPITest.java:5)

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

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

     @Test
public void testException() {
try {
System.out.println("begin...");
int[] arr = new int[]{1};
System.out.println(arr[1]);
} catch (Exception ex) {
throw ex;
}
}

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

如下try...finally是不是也有些奇葩?

     public void testTryFinally() {
try {
System.out.println("begin...");
int[] arr = new int[]{1};
System.out.println(arr[1]);
}finally {
System.out.println("over");
}
}

看似优雅,可是你也没捕获异常呀!

如下处理方式也不可取:

     @Test
public void testException() {
try {
System.out.println("begin...");
int[] arr = new int[]{1};
System.out.println(arr[1]);
} catch (Exception ex) {
throw new MyException( ex.getMessage() );
}
}

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

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

类似如下代码是不是很熟悉?

     public int myBiz() {
int result;
try {
System.out.println("begin...");
int[] arr = new int[]{1};
result = arr[1];
return result;
} catch (Exception e) {
return 0;
}
}

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

哈哈,去翻翻自己写的代码吧~

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,后者有返回值,自我赶脚有些费解!whataboutu?

//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);
}

有关于异常捕获点滴,plus我也揭揭java的短的更多相关文章

  1. 异常捕获 UncaughtExceptionHandler MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Android全局异常捕获

    PS:本文摘抄自<Android高级进阶>,仅供学习使用 Java API提供了一个全局异常捕获处理器,Android引用在Java层捕获Crash依赖的就是Thread.Uncaught ...

  3. .NET 基础 一步步 一幕幕[数组、集合、异常捕获]

    数组.集合.异常捕获 数组: 一次性存储多个相同类型的变量. 一维数组: 语法: 数组类型[] 数组名=new 数组类型[数组长度]; 声明数组的语法: A.数据类型 [] 数组名称= new 数据类 ...

  4. MVC 好记星不如烂笔头之 ---> 全局异常捕获以及ACTION捕获

    public class BaseController : Controller { /// <summary> /// Called after the action method is ...

  5. atitit.js浏览器环境下的全局异常捕获

    atitit.js浏览器环境下的全局异常捕获 window.onerror = function(errorMessage, scriptURI, lineNumber) { var s= JSON. ...

  6. C#中的那些全局异常捕获

    1.WPF全局捕获异常     public partial class App : Application     {         public App()         {    // 在异 ...

  7. Spring-MVC开发之全局异常捕获全面解读

    异常,异常 我们一定要捕获一切该死的异常,宁可错杀一千也不能放过一个! 产品上线后的异常更要命,一定要屏蔽错误内容,以免暴露敏感信息! 在用Spring MVC开发WEB应用时捕获全局异常的方法基本有 ...

  8. JavaScript异常捕获

    理论准备 ★   异常捕获 △ 异常:当JavaScript引擎执行JavaScript代码时,发生了错误,导致程序停止运行: △ 异常抛出:当异常产生,并且这个异常生成一个错误信息: △ 异常捕获: ...

  9. SQLServer异常捕获

    在SQLserver数据库中,如果有很多存储过程的时候,我们会使用动态SQL进行存储过程调用存储过程,这时候,很可能在某个环节就出错了,但是出错了我们很难去跟踪到出错的存储过程,此时我们就可以使用异常 ...

随机推荐

  1. Imu_tk算法流程及数据采集要求和标定程序参数设置

    Imu_tk算法流程 由于VIO中,普遍使用的是精度较低的imu,所以其需要一个较为准确的内参数和noise的估计.Noise大家通常使用Allan方差进行估计可以得到较为可信的结果,这里不赘述了.内 ...

  2. TinyMind 多标签图像分类竞赛 之路

    竞赛传送门:https://www.tinymind.cn/competitions/42 我们就是傻狗天仙配啦~ 决赛排行榜: 这次比赛感谢第一名的 baseline:https://blog.cs ...

  3. background属性解释

    如background: url(images/img1.jpg) no-repeat 0 0; 其中的 0 0,前一个是横坐标上的数,后一个表示纵坐标上的数,而很神奇的是,作为参考的坐标原点不是永远 ...

  4. Django:模型model和数据库mysql(二)

    上一篇把简单的模型与数据库的搭建写了一遍,但模型中有很多深入好用的写法补充一下. 同样的栗子,建立新的模型与数据库来写一写 1.依然是搭建环境 >>>django-admin sta ...

  5. python数据结构之图论

    本篇学习笔记内容为图的各项性质.图的表示方法.图ADT的python实现 图(Graph) 是数据结构和算法学中最强大的框架之一(或许没有之一).图几乎可以用来表现所有类型的结构或系统,从交通网络到通 ...

  6. Go编写的并行计算示例程序

    Go编写的并行计算示例程序 package main import "fmt" const ngoroute = 1000000 func f(left, right chan i ...

  7. day0321 生成器

    一.生成器 1.迭代器: 1.1.调用方法直接返回 1.2.可迭代对象通过执行iter方法得到 迭代器的优势:节省内存. 2.生成器:有些情况我们也需要也需要节省空间,只能是自己写来实现迭代器的功能就 ...

  8. iOS-方法之+ initialize 与 +load

    Objective-C 有两个神奇的方法:+load 和 +initialize,这两个方法在类被使用时会自动调用.但是两个方法的不同点会导致应用层面上性能的显著差异. 一.+ initialize ...

  9. [administrator] rpmbuild

    rpmbuild 1.  rpm是什么 RPM = RPM Package Manager = Redhat Package Manager https://en.wikipedia.org/wiki ...

  10. [development][dpdk][hugepage] 大页内存的挂载

    参考: [development][dpdk][hugepage] 为不同的结点分配不同大小的大页内存 完成了以上内容之后, 下一步需要做的是挂载, 大页内存只有被挂载了之后,才能被应用程序使用. 挂 ...