CodeGym /課程 /JAVA 25 SELF /IntelliJ IDEA 除錯 (Debug)

IntelliJ IDEA 除錯 (Debug)

JAVA 25 SELF
等級 14 , 課堂 6
開放

1. Bug

程式設計師有自己的術語。第一個您會頻繁接觸到的詞就是 Bug(源自英文,意指昆蟲)。這個詞代表程式中的錯誤,導致程式行為異常、崩潰或產生奇怪的結果。

如果程式運行怪怪的,但程式設計師堅持這就是原本的設計,通常會說:「這不是 Bug,是 Feature(功能)」。網路上充滿了關於這個梗的迷因。

關於 Bug 和 Feature 的迷因

歷史背景

傳說在 1947 年 9 月,哈佛大學的科學家在測試 Mark II 電腦時,它發生了故障。檢查所有電路後,他們發現一隻真正的飛蛾卡在繼電器中間。他們將這隻昆蟲貼在日誌上,並註記:「First actual case of bug being found」(第一次發現真實 Bug 的案例)。

從那時起,尋找並修復錯誤的過程就被稱為 Debug(除錯)。

日誌中第一個 Bug 的照片


2. Debug Mode (除錯模式)

為了找到錯誤,程式設計師會使用 Debugger。這是 IntelliJ IDEA 內建的特殊工具,可以讓程式暫停執行,並讓您窺探其「引擎蓋下」的運作情形。

IntelliJ IDEA 可以用兩種模式執行您的程式:

模式 圖示 快速鍵 說明
Run (一般執行) Play 圖示 Shift+F10 (Win/Lin)
Ctrl+R (Mac)
程式從頭到尾直接執行。
Debug (除錯模式) 蟲子圖示 Shift+F9 (Win/Lin)
Ctrl+D (Mac)
程式可以在指定位置暫停。

在除錯模式下,您可以逐行執行程式,同時觀察變數值的變化。

3. 中斷點 (Breakpoints)

為了讓 Debugger 知道在哪裡停止,您必須設置 Break Point(中斷點)。沒有它,程式就會像平常一樣一口氣跑到結束。

我們來實作一個範例。我們將乘法邏輯獨立出來放到一個方法中,以展現除錯器的強大功能。將此程式碼複製到 IDEA 中:

public class Main {
    public static void main(String[] args) {
        int sum = 0;
        for (int i = 1; i <= 5; i++) {
            int result = calculateMultiply(i);  // <--- 我們想在這裡暫停
            sum += result;
            System.out.println("Step: " + i + ", Result: " + result + ", Sum: " + sum);
        }
        System.out.println("Final Sum: " + sum);
    }

    public static int calculateMultiply(int number) {
        return number * 2;
    }
}

任務:我們想觀察變數在迴圈內部的變化,並進入我們的方法內部查看。

動作:在程式碼行 int result = calculateMultiply(i); 左側的灰色窄條點擊滑鼠。會出現一個紅點。

IDEA 編輯器顯示帶有紅色中斷點的 Java 程式碼

現在,透過 Debug(蟲子圖示)執行程式。程式啟動後會立即在執行該行之前「凍結」。

IDEA Debugger 在中斷點處暫停,顯示反白的高亮執行行

4. 控制操作:F8, F7, F9

當程式處於暫停狀態時,您的 Debugger 面板上方會有一個控制台。

顯示 Step Over, Step Into, Resume 按鈕的 Debugger 工具列

F8 — 逐步執行 (Step Over)

按下 F8。程式會執行當前行(呼叫方法、取得結果)並跳到下一行 sum += result;

執行移至 sum += result; 顯示內聯數值

再按一次 F8。程式會執行數值相加。您會看到變數值發生了變化。

Variables 面板中更新後的 sum 和 result 變數

再按一次 F8。您會看到主控台 (Console) 的輸出。

顯示 Step 1 的主控台輸出

這是最基本的移動方式:逐行執行,而不深入方法的內部細節。

F9 — 繼續執行 (Resume Program)

我們的迴圈從 1 到 5。要按 5 次 F8 才能走完一圈,這很花時間。那如果是 1,000 次迭代的迴圈呢?

按下 F9。程式會「解凍」,執行當前迭代中剩餘的所有程式碼,進入第二圈,然後……再次在 Breakpoint 處暫停。

按下 F9 跳轉至迴圈的下一次迭代,i=2

透過這種方式,使用 F9 您可以快速略過迴圈:按一下,跑一輪迭代。

變數顯示第二次迭代的值

F7 — 進入函式 (Step Into)

如果在程式碼中遇到方法呼叫(在我們的例子中是 calculateMultiply(i)),且您按下 F8,Debugger 只會執行它並繼續。但如果您想看該方法內部如何運作,請按下 F7

當程式在 int result = calculateMultiply(i); 這一行暫停時,嘗試按下 F7。Debugger 會將您帶入 calculateMultiply 方法內部,您會看到數值是如何傳遞給 number 參數的。

進入 calculateMultiply(int number) 方法內部

Shift + F8 — 跳出函式 (Step Out)

如果您不小心在 System.out.println(...) 行按下了 F7,結果進入了 Java 系統程式碼的深淵怎麼辦?閱讀數千行別人的程式碼既無聊又難懂。

按下 Shift + F8。程式會快速執行完當前方法中剩餘的程式碼,並將您帶回原來的地方(您的 main 方法)。

從 PrintStream/System.out 方法跳出並回到 Main

5. 去哪裡查看數值?

回到我們的迴圈範例。

顯示 Variables 和 Frames 分頁的 Debugger 視窗概覽

方法 1:Inline Debugging (行內除錯)

直接看程式碼編輯器。IDEA 會在每一行的右側用灰色字體顯示當前數值。

方法 2:Variables 面板

在下方的 Debugger 視窗中,有一個 Variables 分頁。那裡顯示了所有當前的變數。

關於 Java 的重要說明: 基本型別(例如 int)會直接顯示其數值。但物件和陣列(例如 String[])內部儲存了大量資料。要查看其內容,必須點擊變數左側的小箭頭來「展開」物件。

方法 3:Frames 面板

變數左側有一個清單,稱為 Frames (呼叫堆疊/呼叫框架)。它顯示程式目前處於哪個步驟。

例如,標記 main:6, Main 意味著:

  • 您位於 Main 類別的 main 方法中。
  • 您在第 6 行暫停。

這是您在程式碼中的確切位置。如果您進入另一個方法(在 calculateMultiply 上按 F7),此清單上方會出現一筆新的記錄 calculateMultiply:13, Main,指出新方法是從前一個方法呼叫的。

6. Evaluate Expression (評估運算式)

有時只看變數還不夠。您想問:「如果……會發生什麼事?」

按下 Alt + F8 (Windows/Linux) 或 Option + F8 (macOS)。會開啟 "Evaluate" 視窗。您也可以直接在 Variables 面板下方的輸入列輸入運算式。

在這裡,您可以使用當前的變數編寫任何程式碼。例如,在我們的迴圈中輸入:

sum + 100

按下 Enter,IDEA 就會計算出結果,而不會更動原本的程式。這是您進行實驗的草稿紙。

Evaluate Expression 對話框顯示 sum + 100 及其運算結果

7. Conditional Breakpoints (條件中斷點)

想像一下,您的迴圈有 10,000 次迭代,但錯誤只發生在第 5,000 步。按下 5,000 次 F9 絕非好主意。

對紅色中斷點圓圈點擊滑鼠右鍵。會出現彈出視窗。在 Condition 欄位中輸入 Java 條件,例如:i == 5。點擊 Done

在 Breakpoint 上按右鍵,顯示 Condition 欄位並輸入 i == 5

現在,如果您啟動 Debugger,程式會忽略前 4,999 圈,只有當條件變為 true 時才會停止。這會為您節省數小時的工作時間!

8. 管理所有中斷點

有時新手會在專案的不同檔案中設置太多中斷點,導致程式在意想不到的地方不斷暫停。手動到處尋找紅點很費時。

按下 Ctrl + Shift + F8 (Windows/Linux) 或 Cmd + Shift + F8 (macOS)。會開啟 Breakpoints 視窗。

Breakpoints 視窗 (Ctrl+Shift+F8) 顯示專案中所有已啟用中斷點的列表和勾選框

在這裡您可以看到專案中所有中斷點的列表。您可以取消勾選它們(暫時停用)或按 Delete 鍵刪除。

9. 總結

我們介紹了 Java 開發者尋找錯誤的主要武器。Debugger (除錯器) 能將寫程式從「憑空猜測」轉變為精確的工程作業。

快速找到錯誤原因的能力,在商業開發中甚至比快速寫程式的能力更受重視。多練習使用條件中斷點和 Evaluation,這樣就沒有任何 Bug 能逃過您的法眼。

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION