转载:挖掘IntelliJ IDEA的调试功能

 

本篇原文地址:http://qinghua.github.io/intellij-idea-debug/

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

断点

断点类型

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

  1. 行断点(Line Breakpoints):就是我们最经常用的方式。
  2. 方法断点(Method Breakpoints):如果你看到代码调用了一个接口,但不知道具体会跑在哪个实现上,便可以在接口上设置断点,这样不管哪个子类运行到这个方法都会停下来。
  3. 异常断点(Exception Breakpoints):可以在Run -> View Breakpoints中的Java Exception Breakpoints里添加异常的具体类型。这样的话,程序中一旦发生了这种异常马上就会停下来。
  4. 字段断点(Field Watchpoints):可以设置在字段上,这样读写字段都可以触发。需要注意的是,默认只有写才会停下,想要让读取时也停下,需要右击断点,在WatchField access上打勾才行。

条件断点

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

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

无断点暂停

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

调试技巧

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

智能进入(Smart step into)

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

1

actor.action(actionProvider.provide(action.getName()));

 

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

官方文档传送门: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)上,只要实例设置了以下参数,就可以通过远程调试连接到8000端口进行调试。

1

-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y

 

官方文档传送门: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):

这是IDEA 2018年加入的新功能,可以直接在调试中抛出指定的异常。使用方法跟上面的弃栈帧类似,右击栈帧并选择Throw Exception,然后输入如下代码即可:

1

throw new NullPointerException()

 

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

强制返回(Force return):

这是IDEA2015版时增加的功能,类似上面的手动抛异常,只不过是返回一个指定值罢了。使用方法跟上面也都类似,右击栈帧并选择Force Return,然后输入要返回的值即可。如果是void的方法那就更简单了,连返回值都不用输。

官方文档传送门: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开关可以显示方法的返回值。例如以下方法:

1

2

3

private double random() {

return Math.random();

}

 

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

调试流(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,但它能够工作。

如果想设断点的是toStringhashCode等方法,可以在注解上设置断点,也可以在调试时使用: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:切换测试和实现
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值