throw 創建異常物件 → 交給運行時系統。throws 在方法簽名宣告可能拋出的異常 → 提醒調用者。try-catch 攔截並處理 (下一章詳解)。
throw new ExceptionType("錯誤描述");
// 或
ExceptionType e = new ExceptionType("描述");
throw e;
/**
* 將自然數轉為二進制/八進制字串
* @param value 自然數 (>=0)
* @param radix 基數 (只能 2 或 8)
*/
public static String toString(int value, int radix) {
// 1. 前置條件檢查,非法即拋出
if (value < 0) {
throw new IllegalArgumentException("需轉換的數字必須是自然數:value >= 0");
}
if (radix != 2 && radix != 8) {
throw new IllegalArgumentException("基數只能是 2 或 8,當前:" + radix);
}
// 2. 正常邏輯
if (value == 0) return "0";
StringBuilder sb = new StringBuilder();
while (value != 0) {
sb.insert(0, value % radix);
value /= radix;
}
return sb.toString();
}
System.out.println(toString(12, 2)); // 正常:1100
System.out.println(toString(12, 16)); // 拋出 IllegalArgumentException
Exception in thread "main" java.lang.IllegalArgumentException: 基數只能是 2 或 8,當前:16
at Demo.toString(Demo.java:15)
at Demo.main(Demo.java:25)
throw 後代碼永不執行 (編譯器會報 unreachable code)。Throwable 子類實例。
public void readConfig(String path) throws IOException, ConfigException {
// 方法體可能拋出這些異常
}
public MyClass() throws IllegalArgumentException {
// 建構子也可聲明
}
方法 = 藥片,正常功效 = 主邏輯,
throws= 副作用說明。調用者閱讀簽名即知風險,無需看源碼 (二進制分發場景)。
// 底層:直接拋出
public void readFile(String path) throws FileNotFoundException {
new FileInputStream(path); // 可能拋出 FileNotFoundException
}
// 中層:聲明傳遞
public void loadConfig() throws FileNotFoundException {
readFile("config.txt"); // 不捕獲,繼續向上拋
}
// 頂層:最終處理
public static void main(String[] args) {
try {
new App().loadConfig();
} catch (FileNotFoundException e) {
System.err.println("配置檔缺失,使用預設值");
// 記錄日誌、降級邏輯
}
}
class Parent {
void doWork() throws IOException {} // 聲明 IOException
}
class Child extends Parent {
@Override
void doWork() throws FileNotFoundException {} // ✅ 子類異常
// void doWork() throws Exception {} // ❌ 編譯錯誤:Exception 更寬泛
}
| 關鍵字 | 位置 | 作用 | 核心口訣 |
|---|---|---|---|
| throw | 方法體內 | 創建並拋出異常實例 | 「拋出具體錯誤,代碼到此結束」 |
| throws | 方法簽名 | 聲明可能拋出的異常類型 | 「告知調用者風險,受檢必寫」 |
掌握 throw 守護前置條件、throws 誠實宣稱風險,是編寫健壯、可維護、文檔化 API 的基石。