idea中的debug奇淫巧技

工欲善其事,必先利其器

开发过程当中,遇到运行结果和预期的不一致的时候,最有效的方法就是debug了。固然随着开发经验的增长,不经过debug直接看代码有时也能定位问题,可是十分依赖经验和运气,本地debug仍是最直接和完全的解决方式。开发的IDE从eclipse转到idea也好几年了,工做中积累了一些debug经常使用的方法,作个总结,后续有新的姿式了继续来补充。数据库

debug

idea中,debug很是简单,找到你要断点的地方,鼠标左键点击就会出现一个红色小球,这就打上断点了,用debug方式启动程序后,触发你要debug的方法,就会帮你停在这一行。markdown

普通断点.png debug的时候,有各类变量和表达式,有些可能在代码里面并不直接出现,可是对你debug挺重要,这里能够用这个表达式计算器来帮你验证各类表达式的值,不须要本身人工计算。点这个计算器的小图标,而后输入你的表达式,idea就会帮你计算出当前表达式的值。eclipse

表达式计算器.png

条件断点

条件断点是debug中最经常使用的一个技巧,针对像for循环、递归等同一行代码在同一次触发中会反复进入的状况,若是没有条件断点,循环多少次就要在这个地方停多少次,十分麻烦,循环次数多了几乎在这个地方就没法断点。比例循环10000次,当前运行异常能够判定在6378次出了问题,若是不改代码,在循环中的某一行根本没法去打断点,打了以后就要手动放行6378次才能到,这时候只能经过修改代码,增长第6378次的判断,而后打再新增的代码上才能进去debug。有了条件以后,咱们能够在断点上设置一个boolean表达式的条件,表达式为true的时候,才会在断点处停住。例如上面图片中的例子,i是0~4的循环,咱们能够设置一个条件“i == 3”,这样只有在i == 3的时候,断点才会停住。设置条件断点的方法是,在断点上右键,弹出设置条件的面板,而后在条件中填入你的表达式,效果以下图ide

条件断点1.png

条件断点2.png 能够注意到,设置了条件断点后,断点icon的右下角会有一个小问号;运行起来后,并非每次运行到这行代码都会停住,只有在知足i==3的时候,才会停住,这样咱们就能够直接运行到出问题的那个循环。测试

单次断点

有些状况下,咱们但愿这个断点只生效1次就能够了,那咱们就能够设置一下单次断点。 设置的方法是先打开“Breakpoints”(左边侧栏2个红点的图标),找到你的断点,而后勾选上“Remove once hit”就好。idea

单次断点.png

异常断点

这个也是开发中比较经常使用的一种断点方式。想象是否遇到过这样的场景:运行后报了空指针异常或者其余什么异常,可是当前堆栈信息不够判断是哪一行报的,比较传统的作法是,在方法开始的地方打一个断点,而后一步步跟着往下走,而后看看运行到哪一步会形成异常,若是方法比较长的话,这种方式比较费时。异常断点的意思是,并不直接在某一行设置断点,而是在某一种异常上设置断点,方法运行后,idea会帮你停在形成异常的这一行,这样的话,debug起来效率就高多了。 设置异常断点的方法是,先打开“Breakpoints”,点击左上角的“+”,选择到“Java Exception Breakpoints”,而后所搜你想断点的异常,若是是自定义异常,能够选择到“Project”。spa

异常断点1.png

异常断点2.png 设置完成后,并不会在某一行出现断点的标志,由于运行以前idea也不知道哪一行会抛出这个异常,咱们人造了一个空指针异常来验证,以下图所示debug

异常断点3.png 咱们用debug启动后,idea帮咱们停在了“s.length()”这里,这里s是空,因此会抛出空指针异常,这样咱们就能经过异常断点的方式,直接让idea帮咱们定位到了抛出异常的行。3d

强制返回

想象是否遇到过这样的场景:一个方法debug到底10行,咱们已经知道问题了,这时候咱们可能不想执行后面的代码了,由于后面的代码可能有写数据库、有远程调用、有发送消息,若是走了后面的代码咱们后续要再恢复起来会比较麻烦,这时候咱们最多见的操做是直接stop,可是很遗憾,直接stop后,后面的代码仍是会被执行到,以下图所示,“这句在for循环以后执行”这句话在debug结束后仍是会被打印出来。指针

强制返回1.png

强制返回2.png 那有没有办法让后续的代码不被执行呢?这里就可使用强制返回。在Debug时找到Frames模块,里面找到当前正在debug的方法,右键,选择“Force Return”,这样就能够强制返回了,后面的代码不会被执行到。

强制返回3.png 以下图效果,就没有打印出“这句在for循环以后执行”,证实后面的代码缺失没有被执行

强制返回4.png PS:有些同窗的idea可能默认没有打开frames模块,能够在右边这个小魔方这里选择打开

打开frames模块.png

抛出异常

有些时候,咱们在调用方法的地方加了trycatch,或者用AOP的方式增长了统一的异常捕获,可是某一次在catch模块中处理结果和咱们预期不一致,可是咱们本身有的测试数据都不会发生异常,那咱们就很难debug到catch模块的代码了。这时候咱们能够在方法执行的过程当中强制抛出某种异常,这样就能够保证debug到异常捕获的代码。 设置的方法跟强制返回相似,选择抛出异常而且在表达式中建立想要抛出的异常便可:

抛出异常1.png

抛出异常2.png 如上图所示,在method1种强制抛出了空指针异常,咱们在main方法的catch中就捕捉到了这个异常,这样就能够继续debug捕捉到异常后的处理逻辑,以下图所示

抛出异常3.png

Drop Frame

在debug过程当中,有时候在一步步往下走的时候,F8按快了多走了一步,致使关键的一行没有被中止到,这时候咱们只能重来一次,若是遇到不太容易触发的分支,重来一次的代价是比较大的,有没有办法回溯呢?固然并无完整的上一步的功能,可是使用drop frame,可让某个子方法从新走一遍,必定程度上起到了上一步的做用。例如当前在method1种,走到了第2行,可是第1行是咱们的关键行,咱们能够drop掉method1这个方法的frame,这样就会回到调用method1的地方,能够再进入一遍。

第一次,过了method1的第1行,当前在第2行,选择method1这里的Drop Frame

drop1.png

这时候回退到调用menthod1的地方

drop2.png

能够按F7从新进入method1内部

drop3.png

执行结果后,能够看到method1的第1行的sout确实被执行了2次

drop4.png

后记

好了,就先整理这些吧,下次新学了debug的姿式,再来这里补充。

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息