java代码科学DEBUG

Debug可以很好的帮助我们去检查程序中出现的问题,因此我们今天来总结一下debug的小技巧来帮助大家更快的解决作业中的问题

一、断点

断点就是程序运行到这个位置就会停下来,然后我们能观察此刻程序的状态来判断,是否出现异常变量或者不正常的跳转。

在debug模式,注意是debug模式,很多人在运行的时候问我,助教助教,为什么我的程序停不下来啊。那是因为你是运行模式,运行模式是无法命中断点的,只有debug模式才能对断点进行命中,这是很重要的一点,因此下次再有人问为什么断点无法命中,很可能是你模式开错了。

那么哪个是运行,哪个是调试呢?

以IDEA为例,右上角的这个图标

就是我们说的调试,debug,只有在这个模式下才能进行断点的命中。

那么也不是所有的断点都会命中,下面就是无法命中的情况:

运行模式无法命中

断点加在了空行,比如:

断点加在了不可能执行的地方,逻辑原因或者代码执行不到,比如:

这些断点都是不可能命中的,这辈子都不可能。

二、函数调用栈

当断点命中的时候,我们的程序会处于停止的状态,观察下面的控制台,可以看到这些数据

监视框的左边,就是我们所谓的函数调用栈,记录了每一层调用的函数名,点击不同的行能够跳转到该函数跳转的位置,比如我们的断点是加在了sort函数中,那么应该就是在主函数调用sort方法的时候进入的断点,那么我们去点击main函数栈

可以看到main函数的时候当前代码所在的位置

这样我们就可以通过观察函数调用栈来检查是否有逻辑上的错误以及当前代码运行情况

三、变量监视表

右边一点的就是我们的变量监视表,里面列出了当前执行的时候的本地变量,所有被初始化的变量都会显示在这里,我们可以点左边的>来查看具体的值

我们知道info是stockinfo的数组,那么点开就能看到数组内的每一个对象的情况,包括他们中的值,如果有值出现异常能够很快的发现出问题所在

四、单步调试

假如在断点命中了的情况,我们的变量都显得非常的正常,并且我们已经无法分析出哪里出了问题,应该怎么办?

我们可以看到方法栈上面有一些按钮,这些就是我们调试的有力的工具

1、step over 步过

步过可以每次运行一条当前函数的代码,对于方法调用等会直接运行完调用的方法,这种如果我们能够确定调用的方法没有问题,可以使用步过来快速执行下一条语句

比如我们现在在主函数的数据读取下加了断点,那么查看了一下发现stocks的数据都正常,数据正确读取,并且没有乱码显示,那么我们想看看排序后的结果是否正常,那么就使用步过

可以看到直接执行了sort并得到了返回值,并没有进入sort方法执行方法内的代码,这就是步过

2、step into 步入

步入相对步过就是如果执行的代码有方法调用,那么则会进入方法内执行第一句话然后停止,这种能够让我们全方面的观察程序执行的每一句话,较细的去排错

3、force step into 强制步入

举一反三

4、step out 跳出

我们之前看了方法栈,知道了有每层的函数调用,那么step out就是用于直接执行完全该方法,然后停止在外层调用的下一句话,比如:

我们停在了sort方法的这个位置,那么外层函数就是main函数的sort,我们点击step out

可以看到已经跳出到main函数体代码了,但是注意如果step

out不是在函数末尾使用,那么将会执行完毕这个函数然后才跳出,所以只有在保证这个函数没有问题的情况下才可以使用step out,不然就白断了。

五、表达式计算

假如我们认为上述无法看到我们想要的结果,或者可能有些结果不是很好去通过变量监视表来观察,可以使用这个 evaluate expression

可以在这里面进行计算,能够得到这个对象执行的结果,假如一句话嵌套了太多的函数,又不想单独抽出来变量然后再做的话,使用这个办法就能很好的观察每步函数的结果,虽然我们不建议一句话中嵌套许多函数调用。

六、高级断点调试

假如我们在针对两个stock的answer长度相同的时候的排序结果不满意的时候,想知道当两个对象相同的时候比较的结果,那么我们就可以使用这种高级断点

右键断点,能够看到这些属性,可以指定命中

这里我们设置了当s1的answer等于s2的answer相同才命中,然后我们执行试试

七、设置变量

假如我们想要修改filePath,那么右键setValue

就能实时修改变量的值,不过用的比较少