Java中的异常及异常处理
异常的概念
异常是指在程序运行过程中发生的不正常事件,它会中断程序的正常执行流程。Java中的异常机制提供了一种结构化的方法来处理运行时错误,使程序能够优雅地处理错误情况而不是直接崩溃。例如,当试图访问空对象的成员时,会抛出NullPointerException;当数组索引超出范围时,会抛出ArrayIndexOutOfBoundsException。
异常分类
运行时异常(RuntimeException)
运行时异常又称非检查异常(unchecked exceptions),是RuntimeException类及其子类。这类异常通常由程序逻辑错误引起,编译器不强制要求处理,但可能会导致程序终止。常见例子包括:
- NullPointerException:试图访问空对象的成员
- ArrayIndexOutOfBoundsException:数组索引越界
- ClassCastException:类型转换错误
- ArithmeticException:算术运算异常,如除以零
编译时异常(Exception)
编译时异常又称检查异常(checked exceptions),是Exception类中除RuntimeException以外的异常。编译器会强制要求处理这类异常,否则程序无法通过编译。常见例子包括:
- IOException:IO(input/output)-输入输出异常
- SQLException:数据库访问异常
- FileNotFoundException:文件未找到异常
- ClassNotFoundException:类加载异常
- InterruptedException:一个线程被另一个线程中断,抛出该异常。
异常体系结构
Java的异常体系采用层次结构,以Throwable为顶层父类:
Throwable
├── Error (系统严重错误,如OutOfMemoryError,通常无法恢复)
└── Exception├── RuntimeException (运行时异常)└── 其他Exception (编译时异常)
异常处理
try-catch-finally块
使用try…catch语句处理异常时,异常会在内部被捕获和处理,不会传递给JVM,程序可以继续正常执行。
try {// 可能抛出异常的代码FileInputStream fis = new FileInputStream("test.txt");// 其他操作...
} catch (FileNotFoundException e) {// 处理文件未找到异常System.out.println("文件未找到: " + e.getMessage());
} catch (IOException e) {// 处理其他IO异常e.printStackTrace();
} finally {// 无论是否发生异常都会执行的代码// 常用于资源释放if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}
}
throw关键字
用于在方法内部主动抛出异常:
public void withdraw(double amount) {if (amount > balance) {throw new IllegalArgumentException("余额不足");}balance -= amount;
}
注意:抛出异常后,Java虚拟机将终止后续代码的执行,除非使用finally块进行包裹处理。
throws关键字
用于声明方法可能抛出的异常,将异常处理责任转移给上一级调用者:
public void readFile(String path) throws FileNotFoundException {FileInputStream fis = new FileInputStream(path);// 文件操作...
}
最佳实践
- 针对不同的异常类型使用多个catch块,从具体到一般
- 在finally块中释放资源(如文件流、数据库连接)
- 不要捕获异常后什么都不做(空的catch块)
- 自定义异常时继承适当的异常类
- 记录异常信息时使用日志系统而不是简单的printStackTrace()
- 考虑异常对性能的影响,避免过度使用异常处理