起飛,會(huì)了這4個(gè) Intellij IDEA 調(diào)試魔法,閱讀源碼都簡(jiǎn)單了
點(diǎn)擊關(guān)注公眾號(hào),Java干貨及時(shí)送達(dá)
今天給大家?guī)?lái)幾個(gè)我日常工作以及閱讀源碼必備的 IntelliJ IDEA 高級(jí)調(diào)試技巧,分分鐘要起飛的節(jié)奏
斷點(diǎn)處添加 log
很多程序員在調(diào)試代碼時(shí)都喜歡?print?一些內(nèi)容,這樣看起來(lái)更直觀,print 完之后又很容易忘記刪除掉這些沒(méi)用的內(nèi)容,最終將代碼提交到?remote,code review?時(shí)又不得不刪減這些內(nèi)容重新提交,不但增加不必要的工作量,還讓?log tree?的一些節(jié)點(diǎn)沒(méi)有任何價(jià)值
IntelliJ IDEA 提供?Evaluate and Log at Breakpoints?功能恰巧可以幫助我們解決這個(gè)問(wèn)題, 來(lái)看下面代碼:
public?static?void?main(String[]?args)?{
??ThreadLocalRandom?random?=?ThreadLocalRandom.current();
??int?count?=?0;
??for?(int?i?=?0;?i?5;?i++)?{
???if?(isInterested(random.nextInt(10)))?{
????count++;
???}
??}
??System.out.printf("Found?%d?interested?values%n",?count);
?}
?private?static?boolean?isInterested(int?i)?{
??return?i?%?2?==?0;
?}
假如我們想在第 15 行查看每次調(diào)用,隨即出來(lái)的 i 的值到底是多少,我們沒(méi)必要在這個(gè)地方添加任何 log,在正常加斷點(diǎn)的地方使用快捷鍵?Shift + 鼠標(biāo)左鍵,就會(huì)彈出下面的內(nèi)容

勾選上?Evaluate and log, 并自定義你想查看的 log/變量,比如這里的?"interested" + i, 這樣以 Debug 模式運(yùn)行程序(正常模式運(yùn)行,不會(huì)打印這些 log):
interested?7
interested?5
interested?1
interested?2
interested?0
Found?2?interested?values
如果你在多處添加了這種斷點(diǎn),簡(jiǎn)單的看 log 可能偶爾還是不夠直觀,可以勾選上面圖片綠色框線的?"Breakpoint hit" message?:
Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
interested?6
Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
interested?0
Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
interested?9
Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
interested?8
Breakpoint?reached?at?top.dayarch.TestDebug.isInterested(TestDebug.java:49)
interested?1
Found?3?interested?values
Disconnected?from?the?target?VM,?address:?'127.0.0.1:0',?transport:?'socket'
Process?finished?with?exit?code?
如果你想要更詳細(xì)的信息,那就勾選上?Stack trace?(大家自己查看運(yùn)行結(jié)果吧),有了這個(gè)功能,上面說(shuō)的一些問(wèn)題都不復(fù)存在了
字段斷點(diǎn)
如果你閱讀源碼,你一定會(huì)有個(gè)困擾,類中的某個(gè)字段的值到底是在哪里改變的,你要一點(diǎn)點(diǎn)追蹤調(diào)用棧,逐步排查,稍不留神,就可能有遺漏
我們可以在 IntelliJ IDEA 中為某個(gè)字段添加斷點(diǎn),當(dāng)字段值有修改時(shí),自動(dòng)跳到相應(yīng)方法位置
使用起來(lái)很簡(jiǎn)單:
在字段定義處鼠標(biāo)左鍵添加斷點(diǎn)(會(huì)出現(xiàn)「眼睛」的圖標(biāo)) 在「眼睛」圖標(biāo)上鼠標(biāo)右鍵 在彈框中勾選上? Field access?和?Field modification?兩個(gè)選項(xiàng)

如果修改字段值的方法比較多,也可以在?Condition?的地方定義斷點(diǎn)進(jìn)入條件, 有了這個(gè)功能的加成,相信你閱讀源碼會(huì)順暢許多
異常斷點(diǎn)
除了閱讀源碼,一定是遇到了異常我們才開(kāi)始調(diào)試代碼,代碼在拋出異常之后會(huì)自動(dòng)停止,但是我們希望:
代碼停在拋出異常之前,方便我們查看當(dāng)時(shí)的變量信息
這時(shí)我們就用到了?Exception Breakpoints, 當(dāng)拋出異常時(shí),在 catch 的地方打上斷點(diǎn),可以通過(guò)下圖的幾個(gè)位置獲取棧頂異常類型,比如這里的?NumberFormatException

知道異常類型后,就可以按照如下步驟添加異常斷點(diǎn)了:

然后在彈框中選擇 NumberFormatException

重新以 Debug 模式運(yùn)行程序:

程序「一路綠燈式」定位到拋出異常的位置,同時(shí)指出當(dāng)時(shí)的變量信息,三個(gè)字:穩(wěn),準(zhǔn),狠,還有誰(shuí)?
方法斷點(diǎn)
當(dāng)閱讀源碼時(shí),比如 Spring,一個(gè)接口的方法可能被多個(gè)子類實(shí)現(xiàn),當(dāng)運(yùn)行時(shí),需要查看調(diào)用棧逐步定位實(shí)現(xiàn)類,IDEA 同樣支持在接口方法上添加斷點(diǎn)(快捷鍵?cmd+F8/ctrl+F8):
鼠標(biāo)左鍵在方法處點(diǎn)擊斷點(diǎn)(??形狀) 斷點(diǎn)上鼠標(biāo)右鍵
勾選上綠色框線上的內(nèi)容,同樣可以自定義跳轉(zhuǎn)條件 Condition

當(dāng)以 Debug 模式運(yùn)行程序的時(shí)候,會(huì)自動(dòng)進(jìn)入實(shí)現(xiàn)類的方法(注意斷點(diǎn)形狀):

看到這你應(yīng)該想到常見(jiàn)的 Runnable 接口中的 run 方法了,同樣是有作用的,大家可以自行去嘗試了
總結(jié)
相信有以上四種調(diào)試技巧的加成,無(wú)論是工作debug 還是私下閱讀源碼,都可以輕松駕馭了。
最后,來(lái)看看 IDEA 支持的各種斷點(diǎn)調(diào)試類型,如果你只知道紅色小圓點(diǎn),那咱在留言區(qū)好好說(shuō)說(shuō)吧

往 期 推 薦
2、GET 和 POST請(qǐng)求的本質(zhì)區(qū)別是什么?原來(lái)我一直理解錯(cuò)了
點(diǎn)分享
點(diǎn)收藏
點(diǎn)點(diǎn)贊
點(diǎn)在看





