超级有用的idea中的debug奇淫巧技

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享

点击关注#互联网架构师公众号,领取架构师全套资料 都在这里9e6a2d0df761bce5df18f73c3c96acc9.png

0、2T架构师学习资料干货分

上一篇:2T架构师学习资料干货分享

大家好,我是互联网架构师!

工欲善其事,必先利其器

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

debug

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

211c1a4ec54488144145cf4fe51e4f9e.jpeg
普通断点

debug的时候,有各种变量和表达式,有些可能在代码里面并不直接出现,但是对你debug挺重要,这里可以用这个表达式计算器来帮你验证各种表达式的值,不需要自己人工计算。点这个计算器的小图标,然后输入你的表达式,idea就会帮你计算出当前表达式的值。

d03a3ba9f3ed5feafe031fe34f2efde0.jpeg
表达式计算器

条件断点

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

54743a9c0d641aa74ead6e680d4e23fb.jpeg
条件断点
52da70babdfa01703b4643933c700c96.jpeg
条件断点

可以注意到,设置了条件断点后,断点icon的右下角会有一个小问号;运行起来后,并不是每次运行到这行代码都会停住,只有在满足i==3的时候,才会停住,这样我们就可以直接运行到出问题的那个循环。

单次断点

有些情况下,我们希望这个断点只生效1次就可以了,那我们就可以设置一下单次断点。设置的方法是先打开“Breakpoints”(左边侧栏2个红点的图标),找到你的断点,然后勾选上“Remove once hit”就好。

299ff22d52570b528a9d1db1c090bf2f.jpeg
单次断点

异常断点

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

7dfef0c0212d59512e25744a17803724.jpeg
异常断点
0cf55796325996007ac77877ce75d2d1.jpeg
异常断点

设置完成后,并不会在某一行出现断点的标志,因为运行之前idea也不知道哪一行会抛出这个异常,我们人造了一个空指针异常来验证,如下图所示

dc617f0595a15d4437438294be303394.jpeg
异常断点

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

强制返回

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

04f5df63c1bb279631ca3bf887b0c190.jpeg 4139e93567a4a274ac9fcba7b4f78a9d.jpeg

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

944d74beb971fee892a2aec0ace733c7.jpeg
强制返回

如下图效果,就没有打印出“这句在for循环之后执行”,证明后面的代码缺失没有被执行

e37f2309c3e33d51c61764494d81f914.jpeg
强制返回

PS:有些同学的idea可能默认没有打开frames模块,可以在右边这个小魔方这里选择打开

0db246c39f5f3cca2fd3aff8fbd17e0b.jpeg
打开frames模块

抛出异常

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

827cac32938e5cc54b1c02fd26b4d3aa.jpeg 7d03fcdca8883f2321f8b0860ffadb73.jpeg

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

177451e5e6ecedd4ccf8f99ae9b764fb.jpeg

Drop Frame

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

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

6fcae31016514796c5ab0d74e0baec35.jpeg

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

f161413c6d23a07514e697e436c5bbf7.jpeg

可以按F7重新进入method1内部

40790246962ab69e05ad68a09ac6b1c4.jpeg

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

c62a55ea162cb2b1f5c31cab1a709125.jpeg

好了,就先整理这些吧。如果你也有新的 debug 姿势,欢迎留言区里补充与评论。

1、2T架构师学习资料干货分享

2、10000+TB 资源,阿里云盘,牛逼!!

3、基本涵盖了Spring所有核心知识点总结

  · END ·

最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。

如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描上方二维码关注一下,您的支持是我坚持写作最大的动力。

求一键三连点赞、转发、在看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值