1. 异常概述 #
异常是程序执行过程中出现的意外事件,会中断程序的正常流程。Java使用异常处理机制来处理运行时错误,使得程序更加健壮。
2. 异常层次结构 #
Java的所有异常都是java.lang.Throwable类的子类,主要分为两大类:
- Error:表示严重的问题,通常是不可恢复的系统级错误。
- Exception:表示可以被程序处理的异常情况。
Throwable
/ \
Error Exception
\
RuntimeException
3. 检查型异常vs非检查型异常 #
3.1 检查型异常(Checked Exceptions) #
- 除了
RuntimeException及其子类之外的所有异常。 - 必须在代码中显式处理或声明抛出。
- 例如:
IOException,SQLException
3.2 非检查型异常(Unchecked Exceptions) #
RuntimeException及其子类。- 不需要在代码中显式处理。
- 例如:
NullPointerException,ArrayIndexOutOfBoundsException
4. 异常处理 #
4.1 try-catch 块 #
| |
4.2 多重捕获 #
Java 7引入的特性,允许在一个catch块中捕获多个异常:
| |
4.3 try-with-resources #
Java 7引入的特性,用于自动关闭实现了AutoCloseable接口的资源:
| |
5. 抛出异常 #
使用throw关键字抛出异常:
| |
6. 声明异常 #
使用throws关键字在方法签名中声明可能抛出的检查型异常:
| |
7. 自定义异常 #
创建自定义异常类:
| |
8. 异常链 #
在捕获一个异常后抛出另一个异常,同时保留原始异常信息:
| |
9. 最佳实践 #
- 只在异常情况下使用异常。
- 捕获具体的异常,而不是笼统地捕获
Exception。 - 不要捕获
Throwable或Error。 - 在
finally块中清理资源,或使用try-with-resources。 - 记录异常信息,有助于调试。
- 适当地封装异常,不要暴露敏感信息。
10. 常见异常类型 #
NullPointerException: 尝试使用null对象ArrayIndexOutOfBoundsException: 数组索引越界IllegalArgumentException: 方法接收到不合法的参数IOException: 输入/输出操作失败SQLException: 数据库访问错误
理解和正确使用Java异常处理机制可以显著提高程序的健壮性和可维护性。通过合理的异常处理,我们可以优雅地处理错误情况,提供有意义的错误消息,并确保程序能够从错误中恢复或优雅地退出。
11. 自定义异常的类型 #
11.1 检查型异常 vs 非检查型异常 #
在之前的例子中:
| |
这个CustomException是一个检查型异常。这是因为它直接继承自Exception类,而不是RuntimeException类。
11.2 自定义检查型异常 #
- 继承自
Exception类或其任何子类(除了RuntimeException及其子类) - 必须被显式捕获或在方法签名中声明抛出
- 用于表示程序可以合理地预期和恢复的异常情况
例如:
| |
11.3 自定义非检查型异常 #
- 继承自
RuntimeException类或其子类 - 不需要显式捕获或声明
- 通常用于表示编程错误或不可恢复的状态
例如:
| |
11.4 选择建议 #
使用检查型异常:
- 当你希望强制调用者处理异常情况
- 当异常是可以预期和恢复的
- 例如:文件操作、网络连接问题
使用非检查型异常:
- 当异常表示编程错误(如空指针、非法参数)
- 当异常是不可恢复的
- 当你不希望强制每个调用者都处理这个异常
11.5 示例 #
检查型异常示例:
| |
非检查型异常示例:
| |