編譯器強制處理受檢異常(IOException等),但運行時異常(NullPointerException、ArithmeticException等)若未捕獲,會導致執行緒終止並輸出堆疊追蹤至標準錯誤流。預設行為對GUI/伺服器應用不友善——使用者看到空白畫面或控制台噴紅字。
thread.setUncaughtExceptionHandler(handler),單一執行緒自訂ThreadGroup覆寫uncaughtException(),群組內所有執行緒套用Thread.setDefaultUncaughtExceptionHandler(handler),JVM所有執行緒無專屬處理器時回退三者優先順序:執行緒級 > 群組級 > 全域預設級。
Thread.UncaughtExceptionHandler@FunctionalInterface
public interface UncaughtExceptionHandler {
void uncaughtException(Thread t, Throwable e);
}
單一方法,接收異常發生執行緒與異常物件,開發者可在此記錄日誌、彈出對話框、發送錯誤報告、嘗試恢復等。
public class StackWindow extends JFrame implements Thread.UncaughtExceptionHandler {
private JTextArea textArea = new JTextArea();
public StackWindow(String title, int width, int height) {
super(title);
setSize(width, height);
textArea.setEditable(false);
getContentPane().add(new JScrollPane(textArea));
}
@Override
public void uncaughtException(Thread t, Throwable e) {
// 必須在EDT更新UI
EventQueue.invokeLater(() -> {
setVisible(true); toFront(); // 置頂顯示
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
textArea.append(sw.toString() + "\n\n");
});
}
}
// 測試啟動
public class DumpTest {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler(
new StackWindow("未捕獲異常", 500, 300)
);
new Thread(() -> { int i = 1/0; }).start(); // ArithmeticException
// 模擬使用者按鍵後拋出第二個異常...
}
}
System.setProperty("sun.awt.exception.handler", ...)),非標準API,慎用。logback/log4j2非同步寫入檔案、結合Sentry/Rollbar等錯誤追蹤服務,而非單純UI顯示。ExecutorService提交任務時,異常會被包裝在Future.get()拋出的ExecutionException中,不會觸發UncaughtExceptionHandler,需自行處理。