近期了解到 Idea 的Debug 功能非常强大,早点知道的话就更好了!
本文以SpringMVC 的注解式HelloWorld 为例记录Debug 用法。
1)浏览器一个请求"/hello"发出后,经过一系列Java 类中的方法执行,到达手写的Controller。
<a href="/hello">Hello SpringMVC</a>
最近一个栈经过的类:JDK 的java\lang\Thread.java、sun\reflect\DelegatingMethodAccessorImpl.class等,tomcat 的 util\threads\TaskThread.class (还调用Apache 的Coyote 等包的类) 等,javax\servlet\servlet-api,spring-webmvc-4.0.3 的FrameworkServlet,spring-web-4.0.3 的HandlerMethodInvoker, 等。
2)断点设在hello() 方法体的第一条语句即第12行,以下截图为即将执行至第15行时的状态,即此时第15行尚未执行。
从左到右、从上到下的顺序说明Debug 窗口所有图标、按钮等作用。
- rerun tomcat (Ctrl+F5): 点击后立刻以Debug 方式重新启动项目。
- update tomcat application (Ctrl+F10): 会弹框出来,有4个选项,更新资源、更新类和资源、重新部署、重启,还可选择不再次询问(不勾为好)。
- resume program (F9): 重开运行项目,即不会一行行执行(F8) 程序了;如有接下来还有断点,则运行到下个断点处;配合点击第7个按钮mute breakpoints 则使程序一跑到底。
- pause program: suspend program execution and enable debugging; 暂停,好象没啥用。
- stop tomcat (Ctrl+F2): stop process; 结束进程,点击后立即结束,慎点!
- view breakpoints (Ctrl+Shift+F8): view and manage all breakpoints and watchpoints; 可为断点设置条件。
- mute breakpoints: 忽略之后的所有断点。
- get thread dump: Thread Dump是非常有用的诊断Java应用问题的工具,每一个Java虚拟机都有及时生成显示所有线程在某一点状态的thread-dump的能力。Thread dumps出来的信息包含线程;线程的运行状态、标识和调用的堆栈;调用的堆栈包含完整的类名,所执行的方法,如果可能的话还有源代码的行数。
- restore layout: restore visual elements of debugger session to default state; 还原布局。
- settings: 有5个设置选项,作用不大。
- pin tab: 固定标签。
- close (Ctrl+F4): terminate process; 好象跟第5按钮差不多;会弹框出来,还可选择不再次询问(不勾为好)。
- frames: 图标像个线圈,代表栈;这个下拉框里显示的是当前的栈、其属于哪个组、还有状态(RUNNING / SLEEPING / WAIT),点击可选此栈之前的栈;下拉框下面每行是一个栈帧(frame) (每个方法(函数) 的每次调用,都有它自己独立的一个栈帧)。下拉框右边的漏斗图标,可隐藏/显示库中的栈帧(只是隐藏,debug 时并不会忽略执行)。
- threads: 和frames 作用一样,只是视图不同。红色字显示方法名比较醒目,但没有漏斗功能。
- show execution point (Alt+F10): 显示当前执行代码的位置。
- step over (F8): step to the next line in this file; 执行下一行代码。
- step into (F7): step into the next line executed; 即当前代码是方法时,进入该方法;是赋值语句的话则效果跟step over 是一样的。
- force step into (Alt+Shift+F7): ingore stepping filters for libraries, constructors etc. 忽略进入库的拦截器、构造器等。
- step out (Shift+F8): step to the first line executed after returning from this method; 配合drop frame 使用:比如到达断点后已经执行了下一行或多行代码,点step out(就会进入下一个栈帧), 再点drop frame(就会继续进入下一个栈帧), 再点step out,就回到原断点了(第12行)。
- drop frame: moves execution point back to the method call dropping current method frames from the stack; 把执行点移回到 从栈中弹出当前方法栈帧 的方法调用处,即回退到上一个调用的方法;用起来有点akward。
- run to cursor (Alt+F9): run to the line where the caret(补字号) is; 执行到光标位置,此功能只能前进(位置应在当前位置之后),而不能后退。
- evaluate expression (Alt+F8): evaluate arbitrary expression; 弹出可输入计算表达式调试框。
- Variables 子窗口,三杠图标(类似乾卦) 代表方法体内的本地变量(local variables),p图标代表方法的参数(截图里没有因为hello() 方法没参数),m+眼镜图标代表方法体内刚执行过的方法;
- 本地变量内的f 图标代表成员变量(域 field) 。