Debug 是我们在开发过程中经常会使用到的一种排查问题的手段,我们用它来定位分析异常的出现,以及程序在运行中参数的变化。
IDEA 本身具有很强的调试功能,掌握 IDEA 的一些 Debug 技巧,对我们开发和排查问题的效率会有很大的提升
以 Debug 模式启动程序
在 IDEA 中以 Debug 模式启动程序,Windows 系统用户使用快捷键 shift+F9

打断点进行调试
在左边行号的地方单击左键就可以打上断点,再次点击可以取消,当我们以 Debug 模式启动后,程序运行到断点位置会被阻塞

条件断点在满足某个条件时阻塞,否则直接运行
在遍历某个集合时,我们可以指定条件,在满足条件时进入断点进行调试。或者在方法的入口设置,当入参满足条件时进行调试
在断点处右键,在出现的弹框中输入条件表达式

设置后原来的红色圆点会增加一个小问号

运行程序,在满足条件表达式的时候进入了断点

计算表达式主要用来查看或者设置表达式的值,计算表达式可以执行输入的代码块
当断点执行到某个条件,条件表达式是一个方法的时候,我们可以在计算表达式中直接调用该方法,查看返回值。也可以给给当前变量赋值,来满足条件继续调试
点击 Debug 窗口的 Evaluate Expression... 按钮,或者使用快捷键 Alt + F8

可以在 Expression 输入框中直接输入代码调用方法

可以在打开的计算表达式窗口直接修改变量的值
也可以在控制台的变量区 Variables(变量区可以查看当前断点之前的当前方法内的变量。) 中给变量赋值:

方法断点指将断点打在某个方法上,执行该方法时程序被阻塞
在类的方法上打断点后,断点呈现为菱形,程序在执行到方法的时候会自动阻塞

面对陌生的代码可能会遇见某个接口有多个实现类,我们不清除代码逻辑走的具体是哪个实现类,将断点打在方法上,程序会在运行到某个实现类的时候停下

字段断点将断点打在类的字段上,字段上的断点呈现为眼睛状

右键点击断点可以设置字段是 访问/修改 断住

默认会阻塞字段修改,在程序运行到修改字段的时候断住

异常断点在程序抛出指定异常的时候阻塞
如果程序运行中抛出异常,我们没有日志记录异常信息,可以使用异常断点来排除问题
在 debug 控制台左侧找到 View Breakpoints... 按钮

在弹出框中新增断点,断点类型选择异常类型断点


在类上是没有打断点的,但由于我们在 Breakpoints 中设置了异常类型为 java.lang.NullPointerException 的断点,我们的程序在运行中出现异常的时候会自动断住

打断点调试时不阻塞全部线程,多线程情况下只阻塞一个线程
IDEA Debug 打断点调试时默认阻塞全部线程,当前调试完成后才会继续执行其它线程,远程 Debug 时为了不阻塞所有请求使用
右键点击断点处,可以选择 Suspend 为 ALL 阻塞全部线程 或者 Thread 阻塞一个线程

Debug 控制台显示当前阻塞线程,不影响其它线程请求,可以在控制台处切换线程

在程序断点处增加日志
在程序开发过程中会增加一些日志方便调试,这些冗余的日志不需要提交的时候使用
打开 Debug 控制台的 View breakpoints... 界面,在 Evaluate and log 输入框中输入日志表达式

在断点处会在控制台打印日志

可以在调试中抛出指定的异常,或者强制从某个方法返回结果
运行程序,在 Debug 控制台右键点击栈帧,可以选择 Throw Exception 或者 Force Return

点击 Force Return,设置返回结果为 true,可以看到控制台上显示的是自定义的返回值


点击 Throw Exception,设置抛出的异常,可以看到手动抛出的异常信息


在程序初始化的时候进行 Debug,而不是程序成功运行后断点调试
JDWP(Java Debug Writ Protocol)Java 调试协议参数,我们可以使用 jdwp 命令来进行 Debug
使用 java -agentlib:jdwp=help 可以查看 jdwp 命令
java -agentlib:jdwp=help
Java Debugger JDWP Agent Library
--------------------------------
(see http://java.sun.com/products/jpda for more information)
jdwp usage: java -agentlib:jdwp=[help]|[<option>=<value>, ...]
Option Name and Value Description Default
--------------------- ----------- -------
suspend=y|n wait on startup? y
transport=<name> transport spec none
address=<listen/attach address> transport spec ""
server=y|n listen for debugger? n
launch=<command line> run debugger on event none
onthrow=<exception name> debug on throw none
onuncaught=y|n debug on any uncaught? n
timeout=<timeout value> for listen/attach in milliseconds n
mutf8=y|n output modified utf-8 n
quiet=y|n
服务端应用启动参数
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8080 -jar ***.jar
本地使用远程 Debug 连接