簡體   English   中英

在 Intellij 中,如何在斷點處拋出異常?

[英]In Intellij, how can I throw an exception at a break point?

我看到很多關於如何讓 Intellij 中斷異常的問題。 我正在嘗試做一些不同的事情:我想在斷點處拋出異常,以便我可以看到如果在該代碼處發生異常會發生什么。

我已經想出了強制執行此操作的方法。 例如,如果我有一個名為willBeUsed的變量,我可以點擊斷點並添加一個顯示willBeUsed = null的手表。 最終將觸發 NullPointerException。

但是我想拋出一個IOException來看看會發生什么。 沒有辦法欺騙我的代碼這樣做。 當我添加一個說throw new IOException()的手表時,它給了我一個錯誤,說“意外的令牌”。

作為一種變通方法,我可以修改代碼以拋出異常並重新部署。 但我想知道是否有一種方法可以在不修改源代碼的情況下在調試器中做到這一點。

您可以右鍵單擊堆棧跟蹤並選擇“拋出異常”

在此處輸入圖片說明

(自 2018.1 版本起。參見 JetBrains 問題: IDEA-148408

如何將throw語句放在if塊中,並且只更改條件,例如:

boolean shouldThrowException = false;
// ....
if ( shouldThrowException ) //place breakpoint here
{
    throw new IOException();
}

當您遇到斷點時,將shouldThrowException的值shouldThrowException為 true。

在“調試器”窗口的“框架”部分右鍵單擊當前函數並選擇“拋出異常”。 然后輸入要拋出的異常。

在此處輸入圖片說明

我看不出這是怎么做到的。 我嘗試了兩種方法(也許我的想法會導致其他一些想法

1)我嘗試使用調試器“記錄評估的表達式”來throw new IOException()但我得到的只是一條消息,IDEA 無法評估表達式。

2)我還嘗試設置一個斷點,當它停止時,我打開“評估表達式”對話框以拋出一個新異常,但這也不起作用。

我不認為調試器可以拋出異常。 @Binyamin 的解決方案會起作用,但您已經在問題中提到了這一點。 我只能在 IDEA 中添加,可以取消選中“掛起”復選框並在“日志評估表達式”框中輸入shouldThrowException = true 這將導致調試器僅更改值(並記錄它)但不會停止,這在具有許多並發線程的代碼中非常有用。

我不知道你是否嘗試過這個,但你也許可以創建一個只拋出IOException的靜態方法,然后通過發出Evaluate Expression調用該方法。

簡單示例代碼:

package com.stackoverflow;

import java.io.IOException;

public class Main {
    public static void main(String[] args) {

        doStuff();
    }

    private static void throwException() throws IOException {
        throw new IOException();
    }

    private static void doStuff() {
        System.out.println("doStuff");
    }
}

System.out.println行上設置斷點:

在此處輸入圖片說明

調出Evaluate Expression...窗口並調用throwException方法(evaluate),然后您將在doStuff獲得堆棧跟蹤:

在此處輸入圖片說明

異常當然會在throwException但您也會看到整個調用堆棧。

還有另一種方法可以利用 JVM 熱交換。

假設您正在將代碼部署到某個服務器。 然后,當您啟動應用程序時,請確保打開遠程調試(我認為您在調試和談論部署時就已經這樣做了)。 如果不是,那么它將在本地調試器中正常工作。

現在我有兩個類,Main 和 Other。

package com.stackoverflow;

import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        doStuff();
    }

    private static void doStuff() throws IOException {
        System.out.println("doStuff");
        Other.otherStuff();
    }

    public static void throwException() throws IOException {
        throw new IOException();
    }
}


package com.stackoverflow;

import java.io.File;
import java.io.IOException;

public class Other {
    public static void otherStuff() throws IOException {
        File file = new File("Some_File.txt");
        file.createNewFile();
    }
}

throwException()可以放在任何“全局”可用的地方,例如在某些 util 類中。 現在為了方便,它只是放在我的 Main 類中。

現在我們可以在我們的doStuff()方法中設置一個斷點,並且在那里我們可以更改otherStuff()方法中的代碼,以便它調用我們的靜態throwException()方法。

public static void otherStuff() throws IOException {
    Main.throwException();
    File file = new File("Some_File.txt");
    file.createNewFile();
}

我們必須調用一些方法而不是調用throw new IOException()因為否則我們將在Unreachable statement出現錯誤。

然后我們可以按Ctrl + Shift + F9重新編譯Other 類。 現在它將是 HotSwapped(一個對話框會詢問您是否真的想要這樣做)。

然后按繼續,將拋出異常。

然后可以將代碼恢復到正常狀態。

這樣做的好處是,重新編譯的類甚至可以“通過網絡”熱交換到遠程機器。

重要的是您重新編譯的代碼必須在另一個類中。 設置斷點的同一個類將不會被正確重新加載。

作為一種變通方法,我可以修改代碼以拋出異常並重新部署。 但我想知道是否有一種方法可以在不修改源代碼的情況下在調試器中做到這一點。

您將在調試器中修改代碼,但僅在需要時進行。 然后,您可以恢復小的更改並重新編譯以熱交換回舊代碼。

我希望你能明白(沒有雙關語)。

如果您願意,我可以添加屏幕截圖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM