Java 中的异常是在程序执行期间发生的问题,它们打破了正常的程序流程。了解异常是编写健壮的 Java 代码的关键部分之一。
异常的分类
- Checked Exceptions(编译时异常或受检异常):编译时异常是在编译时由编译器强制检查的异常。这意味着在编译代码时,编译器会检查代码是否处理了可能抛出的异常。如果代码中存在可能抛出编译时异常的操作,必须使用 try-catch 块或者在方法签名中使用 throws 关键字声明异常。
- 常见的编译时异常包括:
- IOException:例如文件读写操作可能会抛出的异常。
- SQLException:与数据库操作相关的异常。
- ClassNotFoundException:当尝试加载类时找不到类文件时抛出的异常。
- Unchecked Exceptions(运行时异常或非受检异常):运行时异常是不需要在代码中显式处理的异常,因为它们通常是由编程错误导致的,例如除以零或访问 null 对象。这些异常在运行时由 JVM 抛出,而不是在编译时由编译器检查。常见的运行时异常包括:
- NullPointerException:当尝试访问 null 对象的方法或属性时抛出的异常。
- ArrayIndexOutOfBoundsException:访问数组元素时超出数组边界引发的异常。
- ArithmeticException:算术操作异常,如除以零。
- ClassCastException:在对象类型转换时发生的异常。
- Errors(错误):这些异常表示了一些严重的问题,通常是系统级的问题,应用程序本身无法解决。例如:OutOfMemoryError。
区别
编译时异常必须在代码中明确处理,否则会导致编译错误,而运行时异常不需要显式处理,可以选择性地处理。
编译时异常通常表示程序在运行时可能出现的外部错误或异常情况,而运行时异常通常表示程序中的逻辑错误或错误使用。
编译时异常是 Exception 类及其子类(不包括 RuntimeException 及其子类)的实例,而运行时异常是 RuntimeException 及其子类的实例。
异常处理
异常处理主要通过以下关键字实现:
- try-catch 块:用于捕获和处理异常。
try
块包含可能引发异常的代码,而catch
块则包含用于处理异常的代码。
try {
// 可能引发异常的代码
} catch (ExceptionType e) {
// 处理异常的代码
}
- finally 块:可选的
finally
块用于包含在try
块中执行后无论是否发生异常都必须执行的代码。
try {
// 可能引发异常的代码
} catch (ExceptionType e) {
// 处理异常的代码
} finally {
// 必须执行的代码
}
- throws 关键字:用于声明方法可能抛出的异常,这些异常由调用该方法的代码捕获和处理。
public void someMethod() throws SomeException {
// 方法体
}
- throw 关键字:用于在代码中抛出异常。
throw new SomeException("Error message");
异常类层次结构
Java 中的异常类都继承自 Throwable 类,主要分为两个子类:Error 和 Exception。Error 表示虚拟机无法解决的严重问题,而 Exception 表示可以通过捕获和处理来恢复的问题。
- Error:表示严重问题,程序无法处理,通常需要进行系统级的处理。
- Exception:表示可以被捕获和处理的问题,分为受检异常和非受检异常。