203. Java 异常 - Throwable 类及其子类

203. Java 异常 - Throwable 类及其子类

概述

在 Java 中,所有可被抛出的异常和错误都继承自 java.lang.ThrowableThrowable 有两个直接子类:

  • Error:表示严重的、通常无法恢复的错误(如虚拟机崩溃、内存溢出等)。
  • Exception:表示程序可以捕获或声明抛出的异常情况,包括检查型(checked)和运行时(runtime)异常。

理解 Throwable 层次结构有助于我们明确何时捕获、何时抛出以及如何设计自定义异常。


Throwable 层次结构

java 复制代码
java.lang.Object
  └─ java.lang.Throwable
       ├─ java.lang.Error
       │    ├─ OutOfMemoryError
       │    ├─ StackOverflowError
       │    └─ ......(其他 JVM 错误)
       └─ java.lang.Exception
            ├─ java.lang.RuntimeException
            │    ├─ NullPointerException
            │    ├─ IllegalArgumentException
            │    └─ ......(其他运行时异常)
            ├─ java.io.IOException
            │    ├─ FileNotFoundException
            │    └─ ......(其他 IO 异常)
            └─ ......(其他检查型异常)
  • 检查型异常(Checked Exception) :非 RuntimeException 的子类,必须在方法签名中 throws 或在代码中 try-catch 处理。
  • 运行时异常(Unchecked Exception) :继承自 RuntimeException,编译器不强制捕获或声明。
  • 错误(Error) :继承自 Error,通常表示无法恢复的问题,通常不捕获。

Error:无法恢复的严重问题

Error 及其子类表示 JVM 层面的严重故障,一般不做捕获。典型示例:

java 复制代码
// 模拟栈深度过大导致的 StackOverflowError
public class RecursionDemo {
    public static void recurse() {
        recurse();  // 递归无终止条件
    }
    public static void main(String[] args) {
        recurse(); // 最终抛出 StackOverflowError
    }
}
  • OutOfMemoryError:内存不足。
  • StackOverflowError:调用栈溢出。

这些错误一般不在应用层捕获,而是通过优化代码或调整 JVM 参数来避免。


Exception:可捕获或声明的异常

1. 检查型异常(Checked Exception)

必须显式捕获或声明。常见于 I/O、网络、数据库等操作。

java 复制代码
public void readFile(String path) throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        System.out.println(br.readLine());
    }
}
  • IOExceptionSQLException 等。

2. 运行时异常(Unchecked Exception)

通常表示程序错误,可选择捕获,但不强制。

java 复制代码
public int divide(int a, int b) {
    return a / b; // 若 b == 0,则抛出 ArithmeticException
}
  • NullPointerExceptionIndexOutOfBoundsExceptionIllegalArgumentException 等。

自定义异常

1. 自定义检查型异常

java 复制代码
// 定义异常
public class InsufficientFundsException extends Exception {
    public InsufficientFundsException(String msg) {
        super(msg);
    }
}

// 使用异常
public class BankAccount {
    private double balance;
    public void withdraw(double amount) throws InsufficientFundsException {
        if (amount > balance) {
            throw new InsufficientFundsException("余额不足");
        }
        balance -= amount;
    }
}

2. 自定义运行时异常

java 复制代码
public class InvalidAgeException extends RuntimeException {
    public InvalidAgeException(String msg) {
        super(msg);
    }
}

public class Person {
    private int age;
    public void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new InvalidAgeException("年龄不合法: " + age);
        }
        this.age = age;
    }
}

在代码中抛出与捕获

java 复制代码
public class Demo {
    public static void main(String[] args) {
        // 捕获并处理自定义检查型异常
        BankAccount acct = new BankAccount();
        try {
            acct.withdraw(1000);
        } catch (InsufficientFundsException e) {
            System.err.println("操作失败: " + e.getMessage());
        }

        // 运行时异常示例
        Person p = new Person();
        try {
            p.setAge(-5);
        } catch (InvalidAgeException e) {
            System.err.println("错误: " + e.getMessage());
        }
    }
}
  • 对检查型异常,必须 try-catch 或在方法签名中 throws
  • 对运行时异常,可根据逻辑选择是否捕获。

小结

  1. Throwable :所有可抛出类型的基类,分为 ErrorException
  2. Error:无法恢复,一般不捕获。
  3. Exception:可捕获或声明,分为检查型和运行时异常。
  4. 自定义异常 :根据需求继承自 ExceptionRuntimeException
  5. 抛出与捕获 :使用 throw 抛出,try-catch-finallytry-with-resources 捕获和处理。

通过以上层次结构与代码示例,能够帮助学员更清晰地理解 Java 异常机制及其设计与使用。

相关推荐
king王一帅4 小时前
Incremark Solid 版本上线:Vue/React/Svelte/Solid 四大框架,统一体验
前端·javascript·人工智能
uzong5 小时前
后端线上发布计划模板
后端
uzong6 小时前
软件工程师应该关注的几种 UML 图
后端
上进小菜猪7 小时前
基于 YOLOv8 的 100 类中药材智能识别实战 [目标检测完整源码]
后端
智航GIS8 小时前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
前端工作日常8 小时前
我学习到的A2UI概念
前端
码事漫谈9 小时前
AI 技能工程入门:从独立能力到协作生态
后端
码事漫谈9 小时前
构建高并发AI服务网关:C++与gRPC的工程实践
后端
徐同保9 小时前
为什么修改 .gitignore 后还能提交
前端
一只小bit9 小时前
Qt 常用控件详解:按钮类 / 显示类 / 输入类属性、信号与实战示例
前端·c++·qt·gui