Java 异常处理

异常体系结构

所有异常和错误的根类是 java.lang.Throwable,它有两个主要子类:

  • Error:表示严重错误,通常是 JVM 内部错误(如 OutOfMemoryErrorStackOverflowError)。应用程序不应捕获或处理,因为程序已经无法恢复。
  • Exception:表示程序可以处理的异常情况,分为两大类:
  • 受检异常(Checked Exception):编译器强制要求处理(捕获或声明抛出)。如 IOExceptionSQLExceptionClassNotFoundException
  • 非受检异常(Unchecked Exception):编译器不强制处理,通常是程序逻辑错误导致。包括 RuntimeException 及其子类(如 NullPointerExceptionIllegalArgumentExceptionArithmeticException)。

text

Throwable
├── Error (不可恢复,不处理)
│   ├── OutOfMemoryError
│   ├── StackOverflowError
│   └── ...
└── Exception
    ├── IOException (受检)
    ├── SQLException (受检)
    ├── ClassNotFoundException (受检)
    └── RuntimeException (非受检)
        ├── NullPointerException
        ├── IndexOutOfBoundsException
        ├── ArithmeticException
        └── ...

异常处理关键字

关键字作用
try包裹可能抛出异常的代码块
catch捕获并处理特定类型的异常
finally无论是否发生异常都会执行的代码块(用于释放资源)
throw手动抛出异常对象(用于方法内部)
throws声明方法可能抛出的异常类型(用于方法签名)
try {
    // 可能抛出异常的代码
    int result = 10 / 0;
} catch (ArithmeticException e) {
    // 捕获特定异常并处理
    System.out.println("除数不能为零:" + e.getMessage());
} catch (Exception e) {
    // 捕获更通用的异常(应放在具体异常之后)
    e.printStackTrace();
} finally {
    // 无论是否异常都会执行,常用于关闭文件、数据库连接等
    System.out.println("资源释放");
}
  • 多个 catch:按顺序匹配,应将子类异常放在前,父类放在后,否则子类永远捕获不到。
  • finally:即使 trycatch 中有 returnfinally 仍会执行(除非 System.exit(0) 终止 JVM)。

throwthrows

  • throw:在方法内部手动抛出异常对象。
if (age < 0) {
      throw new IllegalArgumentException("年龄不能为负数");
  }
  • throws:在方法声明时告知调用者该方法可能抛出的受检异常。
  public void readFile(String path) throws IOException {
      // ...
  }

受检异常 vs 非受检异常

类型特点处理要求典型例子
受检异常编译器会检查必须 try-catch 或在方法上 throwsIOException, SQLException
非受检异常编译器不强制可处理也可不处理(但建议处理逻辑错误)NullPointerException, ArithmeticException

设计原则

  • 受检异常用于可预见的、调用方有能力恢复的情况(如文件不存在,可提示用户换文件)。
  • 非受检异常用于编程错误(如空指针、数组越界),应由开发者修正代码,而不是捕获。

自定义异常

当 JDK 内置异常无法准确描述业务问题时,可以创建自己的异常类。

自定义受检异常(继承 Exception

public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String message) {
        super(message);
    }
}

自定义非受检异常(继承 RuntimeException

public class InvalidUserInputException extends RuntimeException {
    public InvalidUserInputException(String message) {
        super(message);
    }
}

使用示例

public class BankAccount {
    private double balance;

    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException("余额不足,需要 " + amount + ",现有 " + balance);
        }
        balance -= amount;
    }
}

异常处理中的常见坑

  • finally 块中 returnthrow 会覆盖 try/catch 中的返回值,应避免。 java
  try {
      return 1;
  } finally {
      return 2;  // 最终返回 2
  }
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇