首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 異常處理實戰演練:自定義異常、鏈式拋出、try-catch-finally 最佳實踐

     編輯:Java 相關知識

場景建模:上課系統

  • 老師上課依賴電腦
  • 電腦可能藍屏、冒煙
  • 藍屏可重啟恢復,冒煙導致課程無法繼續 → 拋出老師級異常

異常體系設計

// 電腦異常基類
class ComputerException extends Exception {
    public ComputerException(String msg) { super(msg); }
}

// 具體異常
class BlueScreenException extends ComputerException {
    public BlueScreenException(String msg) { super(msg); }
}
class SmokeException extends ComputerException {
    public SmokeException(String msg) { super(msg); }
}

// 老師業務異常
class NoPlanException extends Exception {
    public NoPlanException(String msg) { super(msg); }
}

核心代碼實現

class Computer {
    private int state = 3; // 2=藍屏, 3=冒煙

    public void run() throws BlueScreenException, SmokeException {
        if (state == 2) throw new BlueScreenException("電腦藍屏了");
        if (state == 3) throw new SmokeException("電腦冒煙了");
        System.out.println("電腦運行正常");
    }

    public void restart() { System.out.println("電腦重啟中..."); }
}

class Teacher {
    private Computer computer = new Computer();

    public void teach() throws NoPlanException {
        try {
            computer.run();
        } catch (BlueScreenException e) {
            // 可恢復異常:本地處理,不向上拋出
            computer.restart();
            System.out.println("藍屏已恢復,繼續上課");
        } catch (SmokeException e) {
            // 不可恢復異常:包裝業務語義向上拋出
            throw new NoPlanException("上課無法繼續,原因:" + e.getMessage());
        }
        System.out.println("老師正在上課...");
    }
}

public class ExceptionDemo {
    public static void main(String[] args) {
        Teacher t = new Teacher();
        try {
            t.teach();
        } catch (NoPlanException e) {
            System.out.println("主程序捕獲:" + e); // 輸出: NoPlanException: 上課無法繼續,原因:電腦冒煙了
        }
    }
}

關鍵模式解析

模式代碼體現適用場景
捕獲並處理catch (BlueScreenException) { restart(); }異常可本地恢復,調用方無感知
捕獲轉換拋出catch (SmokeException e) { throw new NoPlanException(...); }底層異常無業務語義,需轉為業務異常
異常鏈保留new NoPlanException(msg, e) (Java 1.4+)保留原始堆棧,便於排查根因
finally 清理資源try { ... } finally { close(); }IO、鎖、連接必釋放
多異常合並捕獲 (Java 7+)catch (BlueScreenException | SmokeException e) { ... }同邏輯處理多種異常
try-with-resources (Java 7+)try (Resource r = ...) { ... }自動關閉實現 AutoCloseable 的資源

最佳實踐清單

  1. 異常分層:底層拋檢查異常,業務層轉非檢查異常或統一錯誤碼
  2. 異常信息豐富:攜帶關鍵上下文 (ID、參數、狀態),而非只拋「失敗」
  3. 不吞噬異常:catch (Exception e) { } 絕對禁止,至少 log.error
  4. 資源在 finally/try-with-resources 關閉
  5. 業務邏輯不用異常控制流程:如用 if (user == null) 代替 try { user.getName() } catch (NPE)
  6. 自定義異常以 Exception 結尾,提供構造器鏈
  7. 全局異常處理器:Spring @ControllerAdvice、Servlet error-page 統一返回友好錯誤

常見反模式

// ❌ 異常控制流程
try { int i = list.get(100); } catch (IndexOutOfBoundsException e) { ... }

// ❌ 吞噬異常
try { risky(); } catch (Exception ignored) {}

// ❌ 過度包裝
throw new MyException("Error", e); // 又在上層包裝 MyException2 → 堆棧膨脹

// ✅ 正確
if (list.size() > 100) { ... }
try { risky(); } catch (SpecificException e) { log.error(e); throw new BusinessException(e); }

總結

異常處理核心三原則:具體捕獲、語義轉換、資源保證釋放。將「電腦冒煙」轉為「課程無法繼續」,體現了異常翻譯思想:底層技術異常 → 業務語義異常。掌握 try-catch-finally、try-with-resources、異常鏈、自定義異常體系,即可編寫健壯、可維護的 Java 代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved