程序员的工作内容,除了写代码大部分时间,因为很多时间都花在了调试代码上。甚至没有调试代码,或者即将调试代码。:)今天我们就来说说调试代码的一些技巧,以及使用IDE提供的调试器快速定位问题的一些方法。看到这里的朋友,不要第一时间把我当成头条党了,往下看。如果你有更好的技巧,请留言。让我们进入正题。1.多线程调试开发多线程应用的朋友应该都有经验。有时候,为了观察多个线程之间变量的不同状态,锁的获取等等,就会想到在代码中加断点调试。当您在IDE中的断点处停止时,您可以切换到另一个线程并运行其他代码,而不会相互影响。当然,这里有个开关,在Eclipse中是默认开启的,而在IntelliJIDEA中是默认不开启的。也就是说,如果在IDEA中给代码加断点,虽然断了一个线程,但其他线程已经执行完了。将线程的suspend设置成和Eclipse模式一样后,也可以开始调试多线程应用了。简单的设置可以直接在断点处,将一个线程断了后suspend为Thread,在线程窗口可以切换到其他线程继续运行。在IntelliJIDEA中切换到这里。我们看到主线程和pool-1-thread-1都处于RUNNING状态,切换到任意一个都可以继续运行。此时,你可以写一个多线程的应用程序,同时将内容存储在ArryList等非线程安全的容器中,然后观察它们为什么是线程不安全的,会出现什么问题,形象生动生动。PS:对了,这就是为什么建议在创建线程的时候起一个有意义的名字,至少是一个有辨识度的名字,不然在这里分不清哪个线程是自己的,切换起来也很麻烦。2、后向执行这里说的后向执行就是有时候我们在调试代码的时候,每一个惰性方法都进入单步调试,当你观察到某个变量值的变化时,某个方法并没有跟进。结果,价值改变了,你必须重新做一遍。靠着回去的功能,可以回去,就像下棋后悔一盘棋的功能一样。当然这个退步的名字是我自己的,在IDE里叫DropFrame。有了这个函数,我们在drop当前Frame之后,改变的变量值就不会恢复了。比如你在当前调用的方法中传入一个List,在方法中向List中添加内容,那么当Drop到达调用方法的地方时,List不会恢复到之前的状态。但是当再次调用这个方法时,你可以观察到List什么时候发生了变化,至少你不需要再次运行程序。你甚至可以在意见分歧后退缩。3.条件断点为了调试代码,需要在你想观察变化的地方加一个断点,然后一步步仔细执行。但是如果是在循环中,或者方法会被多个线程同时调用的时候,你仔细下台调试,发现没有你关心的东西,然后从循环开始往下跑,而且您仍然缺少内容,人们开始生气。其实在加断点的时候,我们可以给断点加上一定的条件,让断点只有在满足指定的条件时才会生效。在IntelliJIDEA中,右击断点,会弹出如下图的条件框,输入指定的条件即可。有了条件断点,可以直接跳过不相关和无趣的代码。4.片段代码不知道用什么名字来描述它。有时在调试过程中,突然想招待一段与此相关但源文件中没有的代码,以观察和协助分析问题。这个时候你会不会把程序停下来,加代码再运行?IDEA中有一个执行代码片段的功能,可以在当前代码的上下文中执行你临时编写的代码。比如当前方法传入了一个List,但是这个方法中少了一个元素,后面需要用到。这时候可以暂时使用片段代码执行的函数,加一个进去。注意,在IntelliJIDEA中,上图红框内的按钮,看起来像一个小计算器,是一个临时执行的功能。点击后会弹出按钮下方的EvaluateExpression框,输入代码,点击右下角的Evaluate。返回值将显示在Result中。这相当于临时改变了变量内容。然后,还可以在对象上调用方法,执行函数,获取属性值等。5.查看变量修改值每个IDE在调试代码时都提供了一个窗口来观察当前的上下文变量值。其实除了查看,一些非final的基本类型也可以直接修改这里的值。这样,如果多次执行循环,每次都可以恢复到想要的值,而无需重新启动程序。【本文为专栏作家“侯书城”原创稿件,转载请通过作者微信公众号“Tomcat物语”获得授权】点此查看本作者更多好文
