187. Java 异常 - 什么是异常?

66 阅读3分钟

187. Java 异常 - 什么是异常?


🚨 什么是“异常”?

在程序运行过程中,有些情况是“非正常的” —— 比如文件找不到、除数为零、数组越界……这些突发事件打断了程序原本的运行流程,这就是 异常(Exception)

✅ 定义:

异常是程序运行时发生的、打断正常执行流程的一种事件。

当异常发生时:

  1. 当前方法会 创建一个异常对象,这个对象封装了错误信息;
  2. 然后将这个对象 抛给 Java 运行时系统
  3. 运行时系统会寻找可以“处理”这个异常的代码块。

这个过程被称为:抛出异常(throwing an exception)


🧱 异常对象中包含什么?

异常对象中通常包含以下信息:

  • 异常的类型(如 NullPointerExceptionIOException 等)
  • 错误发生时的程序状态(栈轨迹、具体位置等)
  • 可选的错误消息(message

Java 是怎么“处理”异常的?

关键概念:调用栈(Call Stack)

可以想象程序运行是一个“方法接着方法调用”的过程。发生异常时,Java 会沿着调用栈往上“寻找处理者” 👇

main() → methodA() → methodB() → methodC() ← 异常发生在这里

Java 会从 methodC 开始,逐层往上查找,寻找能处理此异常的方法。


🧯 什么是异常处理器(Exception Handler)?

异常处理器是一段能够“捕获并处理”异常的代码块。通常使用 try-catch 语句编写:

try {
    // 可能出错的代码
    int result = 10 / 0;
} catch (ArithmeticException e) {
    // 处理异常的代码
    System.out.println("算术异常:除数不能为0!");
}

如果某个方法能处理该异常类型,它就 “捕获(catch)” 了这个异常,程序可以继续运行。


🧭 示例:调用栈中的异常传递过程

public class Demo {
    public static void main(String[] args) {
        methodA();
    }

    public static void methodA() {
        methodB();
    }

    public static void methodB() {
        methodC();
    }

    public static void methodC() {
        int result = 10 / 0; // ArithmeticException
    }
}

此代码运行时会报错:

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Demo.methodC(Demo.java:14)
	at Demo.methodB(Demo.java:10)
	at Demo.methodA(Demo.java:6)
	at Demo.main(Demo.java:2)

Java 沿着调用栈找,但没有任何一个方法提供处理器,所以程序崩溃。


☠️ 如果没人处理异常会怎样?

如果异常从最底层冒到最顶层(main 方法),仍无人处理:

  • 当前线程终止
  • 如果是主线程 → 整个程序崩溃

💡 为什么使用异常比传统错误码更好?

传统方式(C 风格):

int status = doSomething();
if (status == -1) {
    // 错误处理逻辑
}

Java 异常的优势在于:

特点好处
❌ 非常规返回值✔ 不影响主逻辑的返回
❌ 忽略容易✔ 统一强制检查
❌ 错误信息不集中✔ 异常对象封装信息
❌ 嵌套判断混乱✔ try-catch 语义清晰

🔍 常见异常类型

异常类型说明
NullPointerException访问 null 引用的方法或字段
ArrayIndexOutOfBoundsException数组越界
ArithmeticException除以零等算术错误
IOExceptionI/O 操作失败
ClassNotFoundException类未找到

🧾 小结

  • 异常是运行时的问题,用对象表示,用抛出(throw)来传播。
  • Java 使用调用栈寻找可以处理异常的代码块。
  • try-catch 是处理异常的标准方式。
  • 异常使得错误处理逻辑与业务逻辑解耦,提升了代码清晰度。

🎯 建议实践

✅ 编写以下代码练习理解异常处理:

public class TestException {
    public static void main(String[] args) {
        try {
            int[] arr = {1, 2, 3};
            System.out.println(arr[3]); // 越界
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界了!");
            e.printStackTrace(); // 查看异常轨迹
        }
        System.out.println("程序继续执行...");
    }
}