【Code Skills】【Java】1-1 “Exception”的妙用-调试看Log技巧
本文阅读大约需要3分钟
温馨提示
阅读本文需要有一定的Java编程基础(基本语法),需要大致了解try-catch块和几种常见的Exception,然后大家就可以快乐玩耍啦!
太长不看版
不管是看速递版,还是全文,请留几十秒给小凳子留言一下吧~
/**
* 故意制造ArithmeticException异常,通过异常打印堆栈来查看方法调用顺序
*/
try {
int a = 1 / 0;
} catch (Exception e) {
e.printStackTrace();
}
烦人的Exception
相信各位程序员们,(不仅限于Java程序员),很多人都在编程的时候遇到过Exception吧。
不管是初学代码的小码农,遇到的简单计算异常ArithmeticException、数组下标异常IndexOutOfBoundsException、空指针异常NullpointerException,还是在代码海洋中沉浮几载经验老道的程序猿们,什么I/O Exception、ClassNotFoundException、OutOfMemoryException等等都见怪不怪了。
可以说,Exception几乎就是从基础开始往有难度的语法这个阶段,就开始出现了。
但是这位对我们”不离不弃“的老朋友,其实是个黏人精加麻烦鬼——如果只是普通的除数为0或者是下标越界异常倒还好,一旦出现I/O Exception、OutOfMemoryException这种级别的,如果系统复杂度还不小的情况下,调试难度就几何程度地成倍增加了。
况且不仅这样的Exception处理起来很麻烦,还很顽固——有些时候并不是一个地方单一引起的异常,而是连锁反应。也就是说,如果治标不治本的话,分分钟就是“一时改bug一时爽,一直改bug火葬场”。
(别问小凳子怎么知道的,一直改bug都没改到根源这种丢脸的事情,不说也罢)
别小看了try-catch
有人可能会说:“啊小凳子你一定是Java基础没学好,怎么连try-catch块都不知道用来捕捉异常呢?”
没错,Java体系下,的确有try-catch这个结构可以很方便地进行捕捉Exception,以不同的分类来捕捉Exception。
不熟悉的朋友们我们来复习一下——
try {
// ...
// 有可能出现异常的代码
// ...
} catch (Exception e1) { //可以从小类到大类捕获异常
// 捕获e1类异常
} catch (Exception e2) {
// e2范围应比e1大
} finally {
// 该部分可有可无,在try或catch后必然进行的操作可放在finally
}
故意产生Exception再捕捉?输出堆栈找调试根源
你没听错,就是标题的意思。
有人可能会说:“小凳子啊,你不是说Exception很麻烦吗?为什么我们还要手动制造Exception呢?”
小凳子本来也一直认为Exception很麻烦,能避免就避免,不确定就用try-catch(-finally),至少惹不起还不能躲得起吗?但是,有一次看到前辈调试代码让我大开眼界,决定把这个小技巧分享一下。
先上代码——
try {
int a = 1 / 0; // 人为制造ArithmeticException异常
} catch (Exception e) {
e.printStackTrace(); // 打印堆栈调用
}
其实这个代码很简单,加起来也就最多5行,其中3行还是我们熟悉的try-catch结构。
不过还是简单讲一下剩下的两行吧,第2行定义并初始化了变量a(其他语言可以根据语法适度调整),不在try-catch块外定义主要是防止被别的代码段误用。
我们知道,1 / 0 这种除数为零的情况,是必然会报ArithmeticException 异常的。因此可以利用这一点,捕获异常的时候(第4行),打印对应的堆栈,从而可以方便地在相对复杂的系统中找到代码块的程序调用逻辑,从而便于调试解bug。
代码大佬们可以当我没说,但是冗杂系统里面理清头绪这一点还是挺实用的。
好啦,这次的code skills就说这么多啦~ 咱们下次见~
作者叨叨叨
在第一篇文章立的2周flag的DDL下终于产出了第一篇blog,写的时候绞尽脑汁,写完之后浑身轻松。
并不是很厉害的程序员,博客是记录成长的笔记,可能有一些个人表述因为水平原因不一定很准确,(想要没有误差的blog麻烦看其他大佬们的blog或者官网QAQ),如果写得不好麻烦多多包容多提意见!
接下来会继续记录一些遇到的bug、实用编程技巧,希望读者们多多反馈呀!
我是沉迷打码小凳子,“Talk is cheap, show me the code.”