Java异常处理全解析
立即解锁
发布时间: 2025-08-17 02:35:32 阅读量: 2 订阅数: 16 

### Java 异常处理全解析
#### 1. 异常概述
在 Java 中,异常是对象,所有异常都继承自 `java.lang.Throwable` 类。`Throwable` 有两个主要子类:`Exception` 和 `Error`,它们构成了可抛出对象(throwables)的主要类别。
`Throwable` 类提供了一个 `String` 变量,子类可以设置该变量来提供详细信息。同时,`Throwable` 类还提供了以下常用方法来查询异常:
- `String getMessage()`:返回详细信息。
- `void printStackTrace()`:在标准错误流上打印堆栈跟踪信息。堆栈跟踪信息包含了异常抛出时运行时栈上的方法调用序列,也可以通过重载的 `printStackTrace()` 方法将堆栈跟踪信息写入 `PrintStream` 或 `PrintWriter`。
- `String toString()`:返回异常的简短描述,通常包含异常的类名和 `getMessage()` 方法返回的字符串。
异常的抛出源主要有两种:
- JVM 负责抛出的异常。
- 应用程序代码或应用程序使用的任何 API 显式抛出的异常。
以下是部分异常继承层次结构:
```mermaid
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A(Throwable):::process --> B(Exception):::process
A --> C(Error):::process
B --> D(RuntimeException):::process
B --> E(ClassNotFoundException):::process
D --> F(ArithmeticException):::process
D --> G(ArrayIndexOutOfBoundsException):::process
D --> H(ClassCastException):::process
D --> I(NullPointerException):::process
D --> J(IllegalArgumentException):::process
D --> K(NumberFormatException):::process
D --> L(IllegalStateException):::process
C --> M(AssertionError):::process
C --> N(ExceptionInInitializerError):::process
C --> O(IOError):::process
C --> P(NoClassDefFoundError):::process
C --> Q(StackOverflowError):::process
B --> R(IOException):::process
R --> S(FileNotFoundException):::process
R --> T(EOFException):::process
```
#### 2. 异常类型详解
##### 2.1 `Exception` 类
`Exception` 类代表程序通常希望捕获的异常。它的子类 `RuntimeException` 代表了许多在运行时可能出现的常见编程错误。`Exception` 类的其他子类定义了其他类型的异常,例如 `java.io` 包中的 I/O 相关异常(`IOException`、`FileNotFoundException`、`EOFException`、`IOError`)。
- **`ClassNotFoundException`**:当 JVM 尝试通过字符串名称加载类,但找不到该类时会抛出此异常。例如,在使用 `java` 命令启动程序时,如果类名拼写错误,就会出现这种情况。此时,JVM 会抛出该异常,表明无法找到该类,因此无法启动执行。
##### 2.2 `RuntimeException` 类
运行时异常都是 `java.lang.RuntimeException` 类的子类,而 `RuntimeException` 又是 `Exception` 类的子类。由于这些运行时异常通常是由程序中的错误导致的,所以通常将它们视为程序设计中的缺陷,让默认异常处理程序来处理。
- **`ArithmeticException`**:表示尝试进行非法算术运算的情况,例如整数除以 0。通常由 JVM 抛出。
- **`ArrayIndexOutOfBoundsException`**:Java 会在运行时检查数组索引值,当使用无效的索引访问数组元素时,JVM 会抛出该异常。索引值必须满足 `0 <= 索引值 < 数组长度`。
- **`ClassCastException`**:当尝试将引用值强制转换为不合法的类型时,JVM 会抛出此异常。例如,将 `Integer` 对象的引用值强制转换为 `Long` 类型。
- **`IllegalArgumentException` 和 `NumberFormatException`**:
- `IllegalArgumentException`:当方法被调用时传入了非法或不适当的参数,会抛出该异常。例如,`java.util.regex` 包中的 `Pattern` 和 `Matcher` 类以及 `java.util` 包中的 `Scanner` 类的某些方法会抛出此异常。
- `NumberFormatException`:是 `IllegalArgumentException` 类的子类,专门用于在将字符串转换为数值时,如果字符串中的字符格式不适合转换,则抛出该异常。数值包装类的某些方法在转换出错时会抛出此异常。
- **`IllegalStateException`**:当尝试执行某个操作,但运行时环境或应用程序处于不适合该操作的状态时,会抛出此异常。例如,`java.util` 包中的 `Scanner` 类的某些方法,如果在扫描器已关闭的情况下调用,就会抛出该异常。
- **`NullPointerException`**:当尝试将 `null` 值用作引用值来引用对象时,通常由 JVM 抛出此异常。例如,使用 `null` 引用调用实例方法或访问字段。
##### 2.3 `Error` 类
`Error` 类及其子类定义的错误通常不会被显式捕获,并且通常是不可恢复的。大多数此类错误由 JVM 发出信号。
- **`AssertionError`**:Java 断言机制使用该错误。当 `assert` 语句中的条件计算结果为 `false` 时,JVM 会抛出此错误。
- **`ExceptionInInitializerError`**:当静态初始化块或静态变量声明中的初始化表达式计算时出现意外问题,JVM 会抛出此错误。
- **`IOError`**:`java.io` 包中的 `java.io.Console` 类的方法会抛出此错误,以表示发生了严重的、不可恢复的 I/O 错误。
- **`NoClassDefFoundError`**:当应用程序需要某个类,但找不到该类的定义时,JVM 会抛出此错误。例如,在编译时类存在,但在运行时找不到。可能的原因包括命令行中类名拼写错误、`CLASSPATH` 未指定正确路径或包含字节码的类文件已不存在。
- **`StackOverflowError`**:当运行时栈没有足够的空间来存储新的方法激活记录时,会发生此错误,即栈溢出。例如,以下递归方法会导致栈溢出:
```java
public void callMe() {
System.out.println("Don't do this at home!");
callMe();
}
```
#### 3. 检查型异常和非检查型异常
除了 `RuntimeException`、`Error` 及其子类之外,所有异常都称为检查型异常。编译器会确保如果一个方法可能直接或间接抛出检查型异常,该方法必须显式处理它。方法要么捕获异常并采取适当的操作,要么将异常传递给调用者。
`Error` 和 `RuntimeException` 类及其子类定义的异常称为非检查型异常,意味着方法
0
0
复制全文
相关推荐









