Learn
Java/07-exceptions

异常处理

Java 把异常分为两大类:

  • Checked Exception:编译期必须处理(IOException、SQLException)
  • Unchecked Exception:运行时异常,继承 RuntimeException(NullPointerException、IndexOutOfBoundsException)

1. 基本 try/catch

基本捕获
public class Main {
    public static void main(String[] args) {
        try {
            int n = Integer.parseInt("abc");
            System.out.println(n);
        } catch (NumberFormatException e) {
            System.out.println("捕获:" + e.getMessage());
        } finally {
            System.out.println("无论如何都执行");
        }
    }
}

2. 多 catch

多 catch
public class Main {
    public static void main(String[] args) {
        String[] tests = {"42", "abc", null, "3.14"};
        for (String s : tests) {
            try {
                int n = Integer.parseInt(s);
                System.out.println(s + " -> " + n);
            } catch (NumberFormatException e) {
                System.out.println(s + " 不是整数");
            } catch (NullPointerException e) {
                System.out.println("输入为 null");
            }
        }
    }
}
💡Java 7+ 多异常合并
try { ... }
catch (IOException | SQLException e) { ... }

注意:合并的异常类型不能有继承关系。

3. throw 与 throws

throw 与 throws
import java.io.IOException;
 
public class Main {
    // throws 声明可能抛 checked 异常
    static String readFirst(String[] arr) throws IOException {
        if (arr == null || arr.length == 0) {
            throw new IOException("数组为空");
        }
        return arr[0];
    }
 
    public static void main(String[] args) {
        try {
            System.out.println(readFirst(new String[]{"hello", "world"}));
            System.out.println(readFirst(new String[]{}));
        } catch (IOException e) {
            System.out.println("IO 错误:" + e.getMessage());
        }
    }
}

4. try-with-resources(推荐)

自动关闭实现了 AutoCloseable 的资源(流、连接等)。

try-with-resources
import java.io.*;
 
public class Main {
    public static void main(String[] args) throws IOException {
        // 等价于 try + finally close,但更简洁
        try (var br = new BufferedReader(new StringReader("line1\nline2\nline3"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println("读取: " + line);
            }
        }  // 自动调用 br.close()
    }
}

5. 自定义异常

自定义异常
public class Main {
    static class InsufficientFundsException extends Exception {
        private final double balance;
        private final double amount;
        InsufficientFundsException(double balance, double amount) {
            super(String.format("余额 %.2f,尝试取款 %.2f", balance, amount));
            this.balance = balance;
            this.amount = amount;
        }
        public double getBalance() { return balance; }
        public double getAmount() { return amount; }
    }
 
    static void withdraw(double balance, double amount) throws InsufficientFundsException {
        if (amount > balance) throw new InsufficientFundsException(balance, amount);
        System.out.printf("取款 %.2f 成功,余额 %.2f%n", amount, balance - amount);
    }
 
    public static void main(String[] args) {
        try {
            withdraw(100, 200);
        } catch (InsufficientFundsException e) {
            System.out.println("失败:" + e.getMessage());
        }
    }
}

6. 常见异常一览

异常类型触发
NullPointerExceptionunchecked访问 null 引用
ArrayIndexOutOfBoundsExceptionunchecked数组越界
NumberFormatExceptionunchecked数字解析失败
ArithmeticExceptionunchecked除以 0
ClassCastExceptionunchecked类型转换失败
IOExceptioncheckedI/O 错误
FileNotFoundExceptionchecked文件不存在
SQLExceptioncheckedSQL 错误

🎯 练习

健壮整数解析
// 任务:实现 safeParse(String s) -> OptionalInt
// 解析成功返回包含值的 OptionalInt,失败返回 OptionalInt.empty()
// 期望:safeParse("42")=OptionalInt[42], safeParse("abc")=OptionalInt.empty
 
import java.util.OptionalInt;
 
public class Main {
    static OptionalInt safeParse(String s) {
        // 补全代码
        return OptionalInt.empty();
    }
 
    public static void main(String[] args) {
        System.out.println(safeParse("42"));
        System.out.println(safeParse("abc"));
        System.out.println(safeParse(""));
    }
}

小结

  • ✅ try/catch/finally 捕获异常
  • ✅ throw 主动抛;throws 声明可能抛 checked 异常
  • ✅ try-with-resources 自动关闭资源
  • ✅ 自定义异常继承 Exception(checked)或 RuntimeException(unchecked)
  • ✅ 优先处理具体异常类型,不要 catch (Exception e) 吞所有

下一章 Lambda 与 Stream API。