挖掘IntelliJ IDEA的调试功能

本文介绍了IntelliJ IDEA的一些相对不那么广为人知,但是又很实用的调试功能。希望能让你的IDE发挥出最大的功效!本文使用的IDEA版本是社区版,快捷键是。本文的兄弟篇是挖掘IntelliJ IDEA的实用功能。

断点

断点类型

一般来说调试时,我们都是在代码行上鼠标一点,然后运行测试,遇断点所在的行即停,这就是所谓的行断点。IDEA支持以下几种断点类型:

行断点(Line Breakpoints):就是我们最经常用的方式。

方法断点(Method Breakpoints):如果你看到代码调用了一个接口,但不知道具体会跑在哪个实现上,便可以在接口上设置断点,这样不管哪个子类运行到这个方法都会停下来。

异常断点(Exception Breakpoints):可以在Run->View Breakpoints中的Java Exception Breakpoints里添加异常的具体类型。这样的话,程序中一旦发生了这种异常马上就会停下来。

字段断点(Field Watchpoints):可以设置在字段上,这样读写字段都可以触发。需要注意的是,默认只有写才会停下,想要让读取时也停下,需要右击断点,在WatchField access上打勾才行。

条件断点

断点是可以设置条件的,这样便可以只在关心的时候停下来。比如说循环里处理一堆字符串,但是只关心特定的字符串,那条件断点便可以派上用场。按住Shift键设置断点,或是右击断点之后选择More来打开以下界面

上图就是设置条件断点的界面,直接在Condition里输入条件即可,如。需要注意的是,Suspend默认是没有打勾的,必须勾选上才能让程序暂停。另外,辛辛苦苦设置的特定断点,是可以拖拽到别的地方去的,这样就省的到处敲来敲去的了。还有一个小技巧是按住Alt的同时设置断点,可以让断点仅停一次便自动消失。在设置临时断点时有点用。

无断点暂停

如果在很长的循环时不知道程序运行到哪里了,可以在调试时点击调试窗口上的Pause Program,这样程序便能在当前执行的地方暂停。另外,运行到光标(Run to cursor)也可以在没有设置断点的时候让程序运行到光标所在行时暂停。

调试技巧

下面介绍一些调试的小技巧。

智能进入(Smart step into)

当调试程序运行到类似这样的句子时,如果你想看的是方法,那么进入这个方法就相对麻烦一些。

这时可以使用调试窗口上的智能进入,程序会弹出一个对话框,我们选择需要的调用处即可。算是一个提升调试效率的小技巧。

官方文档传送门:https://www.jetbrains.com/help/idea/debugging-code.html#d181035e286

表达式评估(Evaluate expression)

这应该是大部分人都知道的技巧了,可以通过表达式评估来重新赋值当前的变量,以便让程序运行到其它的分支去。当然也可以在Variables窗口中,右击想要改变的变量,选择Set Value。不过表达式评估里可以轻松增加新变量、动态import新类库等,功能更加强大。

官方文档传送门:https://www.jetbrains.com/help/idea/evaluating-expressions.html

远程调试(Remote debug)

如果运行的实例在其它机器(或者虚拟机、docker)上,只要实例设置了以下参数,就可以通过远程调试连接到端口进行调试。

官方文档传送门:https://www.jetbrains.com/help/idea/debugging-code.html#d181035e408

对于IDEA来说,只需要在Run->Edit Configuration里,增加一个Remote,设置主机Host和端口Port,然后调试它即可。

弃栈帧(Drop frame)

Visual Studio好的一点是调试时可以拖拽当前执行的位置,方便反复查看。虽然IDEA没有这样的功能,但是它可以使用弃栈帧来把当前调用栈的第一栈帧丢弃掉,相当于重新开始当前调试的方法。使用方法也算简单,在要丢弃的栈帧上右击,选择Drop Frame即可。或者直接单击调试窗口的Drop Frame按钮。不过需要注意的是,如果对象在子方法运行时发生了变化,是不会再变回去的。

官方文档传送门:https://www.jetbrains.com/help/idea/debugging-code.html#d181035e308

强制抛异常(Throw an exception):

官方文档传送门:https://www.jetbrains.com/help/idea/altering-the-program-s-execution-flow.html#throw_exception

强制返回(Force return):

官方文档传送门:https://www.jetbrains.com/help/idea/altering-the-program-s-execution-flow.html

自动载入变化代码(Reload changes)

利用Java虚拟机提供的HotSwap功能,我们可以做到一边调试一边改代码。只要在修改完代码之后,点击Run->Reload Changed Classes即可。不过HotSwap有一些限制,例如不支持static的字段和方法等。

官方文档传送门:https://www.jetbrains.com/help/idea/altering-the-program-s-execution-flow.html#reload_classes

显示方法返回值(Show method return values)

调试窗口里的Settings->Show Method Return Values开关可以显示方法的返回值。例如以下方法:

只要在上设断点然后Step Over,或者在方法内部的任何地方设断点然后Step Out一下,便可以在调用处的变量窗口看到一个类似于这样的值:。在这个方法调用没有赋值给变量时(如)还挺有用的。

调试流(Trace Current Stream Chain)

前面说了Visual Studio的好,但是它调试时不能看lambda的值也真是挺恶心的,据说2015版以后开始支持有限的lambda了。IDEA在这方面就做的非常到位。Java 8带来的Stream里面到底是什么,有时候很难知道。通过IDEA提供的这个功能,我们可以很轻松地看到流在各个步骤之间的变化。如下图

展平模式(Flat Mode)更是提供了全局的视角

使用这个功能也非常简单,当程序在lambda表达式的任意处停下时,单击调试窗口的Trace Current Stream Chain按钮即可。

官方文档传送门:https://www.jetbrains.com/help/idea/analyze-java-stream-operations.html

调试内存泄漏(Memory View)

内存泄漏是一个比较头疼的问题,好在IDEA提供了内存分析工具,只要单击调试窗口右上角的Restore ‘Memory’ View就能看到内存窗口,然后点击其中的Click to load the classes list就能看到当前内存的对象分布情况。然后可以据此分析到底是哪个类的对象数量看起来有问题。

官方文档传送门:https://www.jetbrains.com/help/idea/analyze-objects-in-the-jvm-heap.html

调试lombok

如果只是想暂停一下set或get方法,可以使用字段断点,只不过可能会在调试中报错:Source code does not match the bytecode,但它能够工作。

如果想设断点的是、等方法,可以在调试时使用:Refactor->Delombok并选择相对应的注解,然后再使用上文介绍的HotSwap功能,就可以生成代码并按需调试了。最后别忘记把代码恢复回来。

其它

调试异步、线程、死锁、活锁等高级功能,官网上面有详细的教程,可以在用到时参考。

官方文档传送门:https://www.jetbrains.com/help/idea/tutorial-java-debugging-deep-dive.html

快捷键

功能熟悉了以后,熟练使用快捷键能够大幅提高效率。以下是笔者调试时经常使用的快捷键:

F7:进入调用的方法

F8:单步运行

F9:继续运行

Shift+F7:智能进入调用的方法

Shift+F8:跳出当前方法

Alt+F8:表达式评估

Alt+F9:运行到光标

Ctrl+Shift+F9:调试当前光标所在方法或类

Ctrl+Shift+F10:运行当前光标所在方法或类

Shift+F9:调试上次运行的测试

Shift+F10:运行上次运行的测试

Command+Shift+T:切换测试和实现

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180505G0WTZF00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券