IntelliJ IDEA 2020系列(一)必須GET的常用調試技巧-基礎篇

一、 寫在前面

1.1 什麼是斷點

斷點(英語:Breakpoint)是程序中爲了調試而故意停止或者暫停的地方。

調試設置斷點可以讓程序運行到該行程序時停住,藉此觀察程序到斷點位置時,其變量、寄存器、I/O等相關的變量內容,有助於深入瞭解程序運作的機制,發現、排除程序錯誤的根源。

IDEA中一旦設置,斷點將保留在項目中,直到被移除。斷點只能在可執行的代碼行上設置,註釋、字段或方法的聲明以及空行都不是斷點的有效位置。

1.2 爲什麼要學斷點調試

  • 調試是一個程序員最最最基礎的技能。
  • 調試的時間也許比你編碼的時間還要多。
  • 調試技能重要性甚⾄超過學習⼀門語⾔。
  • 不會調試的程序員,肯定不是一個合格的程序員。

本文主要發力講述IDEA調試的相關技能技巧,希望對你能有所幫助。

二、斷點的類型

我發現大部分的小夥伴只會用代碼行左邊鼠標單擊這種最基礎的方式打斷點(即行斷點)。

劃重點: 調試IDEA給我們提供了豐富的斷點類型,讓我們能夠在不同的調試場景下,使用不同的斷點類型來大大提高我們的調試效率。

首先先了解下斷點對話框,先有個直觀的印象,你可以通過快捷鍵ctrl+shift+F8或菜單run-view breakpoints查看,也可以參見三、按鈕介紹的S-5內容。裏面涉及到的內容後面會詳細講解。
斷點對話框

2.1 行斷點

我們最常用的,在每一行前面點一下,出現一個小圓點,這個就是行斷點。這些斷點被分配到源代碼行,並用於針對特定的部分進行調試。
在這裏插入圖片描述
臨時行斷點
創建方法同上,和上面的唯一區別是:把Remove once hit這個複選框給勾選上(此類型斷點其實使用較少)。
在這裏插入圖片描述
這些斷點被分配到源代碼行,並用於針對特定的部分進行調試。命中時,這些斷點將立即被移除。
應用場景舉例
太多了,不說了

2.2 字段斷點

可以設置在字段上,這樣讀寫字段都可以觸發。需要注意的是,默認只有寫纔會停下,想要讓讀取時也停下,需要右擊斷點,在Watch的Field access上打勾纔行。
在這裏插入圖片描述
應用場景舉例
如果在一個複雜的過程結束時,您的某個字段的結果顯然是錯誤的值,那麼設置字段點可能是確定故障來源的最快方法。

2.3 方法斷點

打斷點方式同上,只是它是必須把斷點打在方法那一行上。方法斷點可以按照方法級別跟蹤程序流以及檢查輸入和退出條件。
它有三個特定的參數
在這裏插入圖片描述

  • Watch:
    • “Method entry”:進入方法時激活斷點
    • “Method exit”:出去方法時激活斷點
    • “Emulated”:沒修改過,以下是官方的解釋。

When this option is enabled, IntelliJ IDEA sets a combination of line breakpoints at the first and last statements of a method instead of using a slower “true” method breakpoint. Emulated method breakpoints improve debugging performance and thus are used by default.
We only recommend disabling this option if you are debugging remote code, or if you need to set a breakpoint at native methods or classes without line number information.

翻譯如下:

啓用此選項後,IntelliJ IDEA會在方法的第一行和最後一行語句中設置行斷點,而不是使用速度比較慢的“ true”方法斷點。 仿真方法斷點可提高調試性能,因此默認情況下使用。
僅在調試遠程代碼或在沒有行號信息的native方法或類中設置斷點時,才建議禁用此選項。

應用場舉例
如果你看到代碼調用了一個接口,但不知道具體會跑在哪個實現上,便可以在接口上設置斷點,這樣不管哪個子類運行到這個方法都會停下來。

2.4 異常斷點

比較小衆,用過的人應該不多。
可以在Java Exception Breakpoints裏添加異常的具體類型。這樣的話,程序中一旦發生了這種異常馬上就會停下來。默認會檢索自定義的異常,會優先展示自定義的異常。
在這裏插入圖片描述
在代碼中是看不到的,當捕捉到該異常斷點的時候就會停留在異常斷點處。在這裏插入圖片描述

應用場舉例
有時候程序會拋出異常,我們需要找到爲什麼會拋出,什麼樣的條件會停留異常代碼處。

2.5 斷點類型小結

官方介紹中有如上四種斷點,具體的斷點狀態和圖標形狀如下所示
在這裏插入圖片描述
重點說下三種不太好理解的狀態

  • Muted
    斷點被臨時設置爲無效狀態,可以通過點擊按鈕mute breakpoints實現。典型的應用場景是打了很多斷點,執行到中間某個斷點的時候,想從新再來,又不想把後面的斷點一個個點擊取消,這個狀態代表讓後面的斷點全部失效,一下執行到底。
  • Incactive/dependent
    沒太理解,也沒遇到過,下面是官方文檔說明,待明確後補充

A breakpoint is marked as inactive/dependent when it is configured to be disabled until another breakpoint is hit, and this has not happened yet.

  • Non-suspending
    按shift+鼠標單擊,可以直接設置爲這種狀態,理解爲不被掛起,輸出的信息會包含一部分的源碼信息,有的人還將這個稱之爲源碼斷點
    在這裏插入圖片描述

三、 按鈕介紹

在這裏插入圖片描述
H-橫 S-豎
H-1:Show Execution Point (Alt + F10):如果你的光標在其它行或其它頁面,點擊按鈕可跳轉到當前代碼執行行。
H-2:Step Over (F8):單步跳過,一行一行地往下走,如果這一行上有方法不會進入方法。
H-3:Step Into (F7):單步進入,如果當前行有方法,可以進入自定義的方法內部,不會進入官方類庫的方法。
H-4:Force Step Into (Alt + Shift + F7):強制步入,能進入任何方法,包括官方類庫,查看底層源碼的時候可以用這個進入官方類庫的方法。
H-5:Step Out (Shift + F8):步出,從步入的方法內退出到方法調用處,此時方法已執行完畢。
H-6: Drop Frame (默認無):回退斷點,返回這個方法的調用處,這個方法重新執行,上下文也會回退。
H-7: Run to Cursor (Alt + F9):運行到光標處,你可以將光標定位到你需要查看的那一行,然後使用這個功能,代碼會運行至光標行,而不需要打斷點。
H-8:Evaluate Expression (Alt + F8):計算表達式,4.6章節詳細說明。
在這裏插入圖片描述
S-1:Rerun ‘xxxx’:重新運行程序,會關閉服務後重新啓動程序。
S-2:Resume Program (F9):恢復程序,比如,你在第2行和5行有兩個斷點,當前運行至第2行,按F9,則運行到下一個斷點(即第5行),再按F9,則運行完整個流程,因爲後面已經沒有斷點了。
S-3:Pause Program:暫停程序,啓用Debug,目前沒用過。
S-4:Stop ‘xxx’ (Ctrl + F2):連續按兩下,關閉程序。有時候你會發現關閉服務再啓動時,報端口被佔用,這是因爲沒完全關閉服務的原因,你就需要查殺JVM進程了。
S-5:View Breakpoints (Ctrl + Shift + F8):查看所有斷點。
S-6:Mute Breakpoints:靜默斷點,選擇這個後,所有斷點變爲灰色,斷點失效,按F9則可以直接運行完程序。再次點擊,斷點變爲紅色,有效。如果只想使某一個斷點失效,可以在斷點上右鍵取消Enabled。

四、 幾個常用的調試技巧

4.1 條件斷點

通過設置斷點條件,至於當滿足條件時,才停在斷點處,否則直接運行。
舉個例子,下面是個最最常見的代碼,循環1000次打印一下當前的值
在這裏插入圖片描述
現在我們想在i== 15的時候停留下來看一下執行邏輯,該怎麼操作呢,相信很多同學會在第15行打一個斷點,然後運行debug,一直繼續S-2(Resume Program)按鈕,點擊14次,直到達到i ==15。但是如果是想查看i ==800時候的邏輯,我們不可能點擊800次,這時候條件斷點就顯得很重要了。

如圖所示,右擊行斷點的那個小圓圈,設置一個條件i== 800,然後運行,程序就會在i==800的時候停下來。如下圖所示。這個就是條件斷點。
靈活使用是判斷一個人調試經驗很重要的依據,經常走讀代碼,一般會使用條件斷點的同學技術能力都不會差。
在這裏插入圖片描述

4.2 回到上一步

行話叫斷點回退,顧名思義,就是回退到上一個斷點處,在多個斷點的時候點擊H-6回退到上個斷點位置。
舉個例子,如下。
在這裏插入圖片描述
斷點回退和H-5(步出)的區別是,步出會執行完這個方法,而斷點回退會直接退出這個方法。
這個在代碼調試中也會非常常用,而很多的同學在調試的這種情況會重新的運行一遍代碼,費時費力。

4.3 多線程調試

先來看個例子
在這裏插入圖片描述
IDEA的debug默認的阻塞級別是ALL,會阻塞其它線程,只有在當前調試線程走完時纔會走其它線程。可以在View Breakpoints裏選擇Thread,如圖7.1,然後點擊Make Default設置爲默認選項。
如下所示
在這裏插入圖片描述
這是再執行多線程任務就可以相互不影響,各線程依次輸出了。
在這裏插入圖片描述也可以切換線程,在Frames的下拉列表裏,可以切換當前的線程,執行代碼。
在這裏插入圖片描述

4.4 中斷調試

所謂中斷調試,就是在Debug的時候,中斷流程,不再走剩餘的流程(比如後面的流程要刪除數據庫數據)了。
很多同學應該都是直接關閉重新調試程序,我之前也經常這麼幹。
而如果你點擊停止按鈕,發現後面的程序還是執行了,如下所示,明明在第8行終止了程序,你還是掛了。
在這裏插入圖片描述
這種情況我們可以使用中斷調試,右擊正在執行的斷點擊force return,如下所示,則小明成功的活了下來。
在這裏插入圖片描述

4.5 變量查看

  1. 參數所在行後面會顯示當前變量的值
    在這裏插入圖片描述
  2. 光標懸停在參數上兩秒鐘,則顯示當前變量信息,這種方式最快捷,用的也最多
    在這裏插入圖片描述
  3. 在Variables裏查看,這裏顯示當前方法裏的所有變量
    在這裏插入圖片描述
  4. 在Watches裏,點擊New Watch,輸入需要查看的變量。或者可以從Variables裏拖到Watche裏查看。這種操作在變量層級比較深的時候會非常有用。
    在這裏插入圖片描述

4.6 計算表達式

在第三章中介紹的H-8 計算表達式按鈕,Evaluate Expression (Alt + F8) 。可以使用這個操作在調試過程中計算某個表達式的值,而不用再去打印信息。
如下,很多時候我們想看一下23行的值,一般會在23行之前或者之後打日誌查看,這樣比較麻煩。此時就可以使用計算表達式。在這裏插入圖片描述
5. 讀取變量
在這裏插入圖片描述
6. 計算表達式的強大之處在於不僅可以讀取變量還可以設置變量
在這裏插入圖片描述
你會發現username.isEmpty()爲true,進入到24行並執行了。

五、附錄(主要參考鏈接)

  1. 不做 BUG 仔,必須 GET 的 IDEA 調試技巧.
  2. 官方文檔.
  3. 在Intellij IDEA中使用Debug.

寫在最後
關於IDEA的調試其實還有很多,比如遠程調試/內存泄漏/調試lembda流等這些會在後續的IntelliJ IDEA 2020系列(二)必須GET的常用調試技巧-高級篇中介紹。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章