IDEA的Debug技巧
一、Debug简介和意义
1、Dubug简介
Debug,又叫断点调试,就是对写好的程序进行逐步运行、分解、调试的过程,通过这个过程,我们可以跟踪程序的详细运行过程, 是程序员的开发神器,也是开发必会的一个重要技能。
企业中程序开发和调试的比例为 1:1.5,可以说如果你不会调试程序,就没有办法从事编程工作,同时它也是决定我们进阶到更高层级的一个重要技能!总之,学会它的各种使用技巧,对于程序员而言,相当重要!
2、Debug意义
帮助我们追踪代码的执行流程、更好的理解复杂程序的执行逻辑。
帮助我们快速的进行程序的异常定位或者线上问题追踪。
帮助我们更好的去学习已有框架的源代码,让我们更清晰的了解源码的执行细节和处理逻辑。
二、Debug模式
1、在需要进行调试的代码行前单击,打上红色断点。
2、要进行debug调试,必须以debug模式运行,可以如图中所示一样,右键debug运行,也可以右上角点击debug按钮运 行。我们现在很多开发人员在开发阶段都没有用debug模式启动的习惯,这个习惯最好早点形成,在断点调试的时候能为我们省去重启项目的麻烦。
三、Debug面板
debug面板其实大体可以分为两大类:
第一类是调试功能区,分为:顶部调试功能区、侧栏调试功能区;
另一类是数据展示面板区,又分为:栈帧面板区、变量数据面板区、线程数据面板区。
四、Debug基础功能
1、步过
(F8) :步过(Step over),程序向下执行一行,如果当前行上有方法不会进入该方法,常用于调试过程中不
想进入调用方法体的情况。
2、步入
(F7) :步入(Step into),进入方法内,可以进入自定义方法或三方库方法,JDK官方类库无法进入。
3、强制步入
(Alt + Shift + F7) :强制步入( Force step into),能进入任何方法,一般 Step into 进不去时可以使用,可以帮助我们学习和查看JDK源码
4、步出
(Shift + F8) :步出(Step out),退出方法,跟(force) step into 配合使用 , 从步入的方法内退出到方法调用处,此时方法已经执行完毕,只是还没有完成赋值。调试的时候,有时候会跳入到自己不想查看的方法体,这个时候也可以使用步出进行跳出。
5、运行至光标处
(Alt + F9) :运行至光标处(Run to Cursor),可以让程序运行到光标处 ,无需额外设置断点。
6、运行至下个断点处
(F9) :运行至下个断点处(Resume Program) ,使运行到下一个断点的地方,如果后续没有断点将放行调试。
7、跳至当前调试处 - Show Execution Point
(Alt + F10) :如果你的光标在其它行或其它页,它可以帮助你跳到当前断点执行的行。
五、断点位置
1、行断点
图标为:红色圆点。行断点是最常用的断点,作用为:在断点所在行进行暂停,可以进行逐行调试。
2、字段断点
图标:红色眼睛。作用为:在字段发生变更(默认)或者被访问(需要额外设置)时暂停。
1、如果想知道某个属性在什么时候被修改,可以直接在该字段上打上字段断点,这样字段被修改的时候就会自动暂停。
2、如果我们想在字段被访问时(包括get)也暂停,则可以右键字段断点,将【Field access】勾选上即可。
3、方法断点
图标为:红色菱形。主要作用有如下两个:
1)、在方法签名上打上断点,那么在方法入口(entry)和出口(exit)都会自动暂停。在方法入口暂停可以让我们从头调试整个方法,而在方法出口处暂停可以让我们看到方法执行完毕时,方法内各个变量的数据情况。
2)、有时候我们的一个接口会存在很多实现类,我们短时间内难以分析究竟是运行到了哪个实现类中,这个时候就可以使用方法断点,这个时候将断点打在接口方法上,运行到该方法时,就会自动跳到实际执行的实现类中,而无需通过上下文环境去分析是哪个实现类,大大提高跟踪代码的速度。
其他设置:可以通过自定义设置决定是否需要在入口和出口处停留
4、异常断点
图标:红色闪电。作用:可以在抛出异常的地方进行自动暂停。需要注意的是异常断点无需在具体的代码上打断点的,而是在断点详情页中直接添加,后续在执行时,如果抛出我们监听的异常,则会自动暂停在抛出异常的地方。示例步骤如下
六、Debug高级功能
1、断点回退
又叫降帧,作用:回退到当前方法的调用处。
当我们 Debug 从 A 方法进入 B 方法时,通过降帧可以返回到调用 B 方法前,这样我们就可以再一次调用 B 方法。通常用于当我们快执行完 B 方法后,发现某个重要流程被我们跳过了,想再看一下,则此时可以先回退到 A 方法,然后再次进入 B 方法。
由于方法的执行和结束在 JVM 中对应的是栈帧的入栈和出栈,而栈帧描述的就是方法对应的模型,所以降帧(退帧)对应的效果就是回退到上一个方法。
注意: 断点回退可以在Frames面板上自由选择回退到哪个栈帧
2、计算器表达式
Debug计算器,这是一个非常强大的debug功能,通过这个组件,几乎可以完成调试过程中大部分的事情,包括:查看实时变量、实时变量赋值、执行各种程序操作(包括数据库操作)。
1、查看实时变量:可以查看所有运行过的变量其内部数据状态。
2、实时为变量赋值:可以对运行过的变量进行自定义赋值,且该赋值操作一旦执行, 对后续代码是可见的,
一般用在前端传值失误,运行过程中希望修复变量为正确数据的场景。
3、执行各种程序操作:可以执行所有符合java语法代码,包括执行操作数据库的代码。
注意:操作数据库为不可逆的,哪怕该断点调试结束,对数据库的操作也不会回滚,需要谨慎对待!
3、条件断点
右键单击断点处,可以设置进入断点的条件表达式(返回值为true或false)只有当返回true时才会停在断点处,否则直接运行,一般用在希望满足某个条件然后才调试程序的场景。 如下图所示,为147行设置条件断点,只有当appLogDto的日志级别为ERROR才会进入断点调试:
4、强制返回
对栈面板的目标栈帧右键点击【Force Return】,将会强制结束程序(不会往后执行程序),通常用在需要结束当前断点,而不希望接下来的程序操作数据库的情况,这里值得注意的是,如果选则用结束断点,下面的代码依然会执行(依然会操作数据库)
5、主动抛异常
通过这个功能可以自由的在代码中任意位置构造并且抛出异常,特别是我们希望远程环境抛出一个异常的场景,如果没有该功能,我们可能需要修改代码并且重新部署,测试完后还要修改回来再次部署。而 Throw Exception 则可以直接抛出一个异常,避免了这些繁琐的流程。示例步骤如下:
6、stream流调试