在 Java 中,例外(Exception) 是指在程式執行時發生的錯誤,例如:

  • 除以 0
  • 訪問不存在的檔案
  • 陣列索引超出範圍
  • 轉換字串為數字時格式錯誤

如果不處理這些錯誤,程式可能會崩潰。Java 提供了一套 Exception Handling(例外處理)機制,讓我們可以攔截並適當處理錯誤,確保程式運行穩定。


🔥 1. 例外(Exception) vs. 錯誤(Error)

類型說明例子
Checked Exception(檢查例外)編譯時就需要處理,否則無法編譯通過IOExceptionSQLException
Unchecked Exception(未檢查例外)執行時才會發生,一般是程式邏輯錯誤NullPointerExceptionArrayIndexOutOfBoundsException
Error(錯誤)無法恢復的錯誤,例如 JVM 錯誤OutOfMemoryErrorStackOverflowError

🔥 2. try-catch 基本用法

try-catch 用於 攔截例外 並處理錯誤,避免程式崩潰。

java複製編輯public class ExceptionDemo {
    public static void main(String[] args) {
        try {
            int result = 10 / 0; // 除以 0,會拋出 ArithmeticException
            System.out.println(result);
        } catch (ArithmeticException e) { // 捕捉錯誤
            System.out.println("發生錯誤:" + e.getMessage());
        }
        System.out.println("程式繼續執行...");
    }
}

輸出結果:

csharp複製編輯發生錯誤:/ by zero
程式繼續執行...

👉 優勢:

  • 程式不會因錯誤而終止
  • 提供錯誤資訊給開發者

🔥 3. try-catch-finally

finally 區塊無論是否發生例外,最後都會執行。

java複製編輯public class FinallyExample {
    public static void main(String[] args) {
        try {
            System.out.println("嘗試開啟檔案...");
            int num = 10 / 0; // 這裡會拋出例外
        } catch (ArithmeticException e) {
            System.out.println("發生錯誤:" + e.getMessage());
        } finally {
            System.out.println("關閉檔案...");
        }
    }
}

輸出結果:

csharp複製編輯嘗試開啟檔案...
發生錯誤:/ by zero
關閉檔案...

finally 常用來:

  • 釋放資源(如關閉檔案、釋放記憶體)
  • 關閉資料庫連線
  • 其他 清理(Cleanup) 操作

🔥 4. throwsthrow

👉 throws:方法可能拋出的例外

當方法內可能會發生某些例外,但不想在方法內部處理,而是 讓呼叫者自己決定如何處理,可以使用 throws

java複製編輯public class ThrowsExample {
    public static void checkAge(int age) throws IllegalArgumentException {
        if (age < 18) {
            throw new IllegalArgumentException("年齡必須大於 18 歲!");
        }
        System.out.println("年齡合法!");
    }

    public static void main(String[] args) {
        try {
            checkAge(16); // 這裡會拋出例外
        } catch (IllegalArgumentException e) {
            System.out.println("錯誤:" + e.getMessage());
        }
    }
}

輸出結果:

複製編輯錯誤:年齡必須大於 18 歲!

👉 throw:手動拋出例外

throw 用於手動拋出例外,例如:

java複製編輯public class ThrowExample {
    public static void main(String[] args) {
        throw new RuntimeException("這是一個手動拋出的例外!");
    }
}

這段程式會直接拋出 RuntimeException,導致程式崩潰。


🔥 5. 自訂例外(Custom Exception)

Java 允許我們 自訂例外類別,這在大型專案中特別有用。

👉 定義自訂例外

java複製編輯class AgeException extends Exception { // 繼承 Exception
    public AgeException(String message) {
        super(message);
    }
}

👉 使用自訂例外

java複製編輯public class CustomExceptionExample {
    public static void checkAge(int age) throws AgeException {
        if (age < 18) {
            throw new AgeException("年齡不符合規定!");
        }
    }

    public static void main(String[] args) {
        try {
            checkAge(16);
        } catch (AgeException e) {
            System.out.println("錯誤:" + e.getMessage());
        }
    }
}

輸出結果:

複製編輯錯誤:年齡不符合規定!

👉 什麼時候用自訂例外?

  • 需要更具描述性的錯誤訊息
  • 需要處理特定業務邏輯的錯誤

🔥 6. 多重 catch 處理

當一段程式可能發生多種例外時,可以用 多重 catch 來分別處理不同的錯誤。

java複製編輯public class MultiCatchExample {
    public static void main(String[] args) {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[5]); // 陣列超出範圍
        } catch (ArithmeticException e) {
            System.out.println("數學運算錯誤:" + e.getMessage());
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("陣列索引超出範圍:" + e.getMessage());
        } catch (Exception e) {
            System.out.println("其他錯誤:" + e.getMessage());
        }
    }
}

輸出結果:

pgsql複製編輯陣列索引超出範圍:Index 5 out of bounds for length 3

🎯 總結

例外處理方式作用用法
try-catch捕捉並處理例外try { ... } catch (Exception e) { ... }
finally無論如何都執行finally { ... }
throws方法可能拋出例外public void myMethod() throws IOException
throw手動拋出例外throw new Exception("錯誤")
自訂例外定義專屬錯誤類別class MyException extends Exception {}

🚀 例外處理讓程式更穩定

  • 防止程式崩潰
  • 提供明確的錯誤訊息
  • 保持程式可維護性
  • 讓開發者更容易找到錯誤並修復