工欲善其事,必先利其器。
声明
由于 IDEA 每个人使用的版本不同以及快捷键的设置不同,所以忽略了快捷键的使用。如果不知道快捷键请在 IDEA 工具栏里面点开 Run 菜单即可知悉
IDEA 中的 Debug 简介
什么是 Debug 、怎么打断点以及怎么进入 Debug 咱们这就不介绍了,那个太 Easy 了!实在不知道可以问 度娘。
下面咱们进入看图说话环节,下列图标小伙伴知道是啥功能么?日常开发进行 Debug 使用到哪一些呢?可能也就那一半左右吧!
-
Show Execution Point:显示当前执行点,可以清晰地从图标中看出意思,红色的箭头上面执行完了,箭头下面的是将要执行的内容。那么这个有啥功能呢?从下面的动图可以看到当停留在断点的时候切换到 System 类里面,通过点击此图标即可回到当前断点停留的地方(如果记住快捷键了连鼠标都不用点了)。你是不是还在通过点击 Debugger 下的 Frames 里面的断点调用链来回到当前断点停留的地方呢?赶快使用 Show Execution Point 功能吧!
-
Step Over:单步执行,如果有方法则不进入方法(除非方法里面有断点)
-
Step Into:单步执行,如果有方法则进入方法(请检查你的 IDEA Debugger 里面的设置,一些包里面的方法使用 Step Into 也进不去,可以把下面的 Do not step into the classes 勾取消即可)
-
Force Step Into:基本与 Step Into 功能相同,不同点就是可以强制进入那些 JDK 源码里面。不需要如上面的 Do not step into the classes 设置。
-
Step Out:跳出当前所在的方法,返回调用此方法的地方。
-
Run to Cursor:执行到光标所在位置,可以跳过中间需要执行的代码。
-
Drop Frame:丢弃当前方法,回退上一个方法。如果是 main 方法则不会激活此图标。学”废“了这个妈妈再也不用担心我一不小心错过了断点,还需要重新来啦。
-
Trace Current Stream Chain:对当前 Stream 进行链路追踪,喜欢用 JDK 8 新特性 Stream 来编程的小伙伴可以使用这个功能,谁用谁知道!
-
Evaluate Expression:表达式计算,Debug 功能里面最牛逼的功能,不接受反驳!一切皆可使用这个功能。
IDEA 中的 Debug 基础使用
IDEA 的 Debug 断点分类有哪些?
- 行断点
- 字段断点
- 方法断点
- 异常断点
行断点
这是咱们日常开发最最最经常用的断点。
带有 lambda 表达式的行断点
Line 选项正常行断点,在此行断点停下, lambda 表达式方法不停
入 选项是 lambda 表达式方法会停下
All 选项是 2 种都会停
思考:如果把 lambda 表达换行还会出现上面的三种选项么?
private static void lineBreakpoint() {
System.out.println(1);
Runnable runnable = () ->
System.out.println("1231");
System.out.println("Thread starting");
new Thread(runnable).start();
}
行断点还可以打在类上,用于类实例化时候进入(没有定义构造器)
字段断点
用过此功能的小伙伴举个手。估计有些小伙伴都没听过字段还有断点吧!Talk is cheap. Show me the code. Let’s go!!!
通过右键设置断点的触发类型:修改和访问
日常开发中想找到类中的某个字段是啥时候赋值的最佳选择(暴力手段反射除外)!
方法断点
既然字段都有断点方法为何没有?接下来我们来了解一下方法断点。触发方法断点可以是方法的进入和方法的退出
异常断点
what?异常还有断点?是的!你没有看错。在 Run 菜单下有个 View Breakpoints
可以选择要对哪个异常类进行断点设置,我选择自定义异常 CustomException 类。
在发生异常时进行通知,通知有两种情况,如下图
public static void main(String[] args) {
exceptionBreakpoint();
}
private static void exceptionBreakpoint() {
caughtThrowCustomException();
uncaughtThrowCustomException();
}
private static void uncaughtThrowCustomException() {
throwCustomException("未捕获自定义异常");
}
private static void caughtThrowCustomException() {
try {
throwCustomException("捕获自定义异常");
} catch (CustomException e) {
// ignore
}
}
private static void throwCustomException(String msg) {
throw new CustomException(msg);
}
Caught exception 捕获异常时通知:
Uncaught exception 未捕获异常时通知:
Caught exception + Uncaught exception
肯定有小伙伴会想平时有异常可以从堆栈信息判断出哪一行报错了。但是有没有人像我那么骚把异常捕获了不打日志呢?
IDEA 中的 Debug 高级使用
让我们来进一步了解一些 IDEA 中的 Debug 高级特性
Variables(变量) 区域
可以查看当前方法里面的变量信息,右键变量可以操作变量里面的值或者复制出来以及新建 Watch 等。功能非常强大,等待小伙伴的挖掘!
一次性断点
右键断点点击 More 然后勾选 Remove once hit 即可。
条件断点
在断点上右键就会出现对话框,然后通过 Condition 进行设置相应条件即可,下面只是一个简单的 i 等于 5 的设置,其实可以进行很多复杂的设置,这就留给小伙伴们自己摸索啦。
强制方法返回指定值或指定异常
在进行 Debug 的时候,执行到某个带有返回值的方法时,如果我想指定返回值怎么办?我想抛出异常怎么办?以满足我后面的代码条件处理。
public static void main(String[] args) {
try {
forceReturnOrThrowException();
} catch (Exception e) {
// 异常处理逻辑
}
}
private static void forceReturnOrThrowException() {
System.out.println(add(1, 2));
}
static int add(int a, int b) {
return a + b;
}
调用 add 方法传参是 1 和 2 按照程序 1 加 2 等于 3 ,使用 Force Return 功能返回 5。
抛出异常
智能单步
同一行嵌套多个方法调用,怎么指定执行某一方法?难不成每个方法都有进入然后退出再执行下一个方法?No!No!!让我们来了解一下 Smart Step Into 功能吧!!!
public static void main(String[] args) {
smartStepInto();
}
private static void smartStepInto() {
method(String.valueOf(add(3, 4)));
}
static int add(int a, int b) {
return a + b;
}
static void method(String str) {
System.out.println(str);
}
我只想调用 method 方法,而不执行 add 和 String#valueOf 方法
删除断点或者使断点失效
View Breakpoints 点开之后可以对现有的断点进行删除
Mute Breankponts 点击之后会使所有断点变成无效,断点由红变白
使用 IDEA 进行远程 Debug
为什么远程/本地 Debug 的时候会阻塞别的请求?
比如下面在 echo 请求里面打了断点,先请求 echo,然后再请求 echo2 时候就会被阻塞了!
设置一下断点暂停策略(All 是所有线程,Thread 是当前线程)为 Thread 即可。
远程 Debug 必须保证本地代码与服务器上面的代码完全相同!