概述
Throwable 是 Java 中所有错误(Error)和异常(Exception)的基类,位于 java.lang 包中。它定义了程序运行中可能出现的各类问题的通用处理机制,是 Java 异常处理体系的核心。
一、核心特性
- 继承关系:
Throwable ├── Error(严重错误,通常不可恢复,如 JVM 崩溃) └── Exception(可处理的异常) ├── RuntimeException(未检查异常,如空指针) └── 其他Checked Exception(已检查异常,如IOException) - 关键方法:
getMessage(): 获取异常描述信息。getCause(): 返回引发当前异常的底层原因。printStackTrace(): 打印异常堆栈跟踪。addSuppressed(Throwable): 添加被抑制的异常(Java 7+,用于资源关闭时的异常传递)。
- 异常链:支持通过构造器或
initCause()方法链式传递异常原因。 - 不可变性:Throwable 对象创建后不可修改(线程安全)。
二、应用场景
- 自定义异常:扩展
Exception或RuntimeException定义业务异常。 - 错误日志记录:捕获并记录异常堆栈,便于调试。
- 资源清理:在
finally或try-with-resources中确保资源释放。 - 异常转换:封装底层异常为高层抽象异常(如将
SQLException转为DaoException)。 - 全局异常处理:通过
Thread.setDefaultUncaughtExceptionHandler处理未捕获异常。
三、示例代码
1. 基本异常处理
public class BasicExceptionDemo {
public static void main(String[] args) {
try {
int result = divide(10, 0);
System.out.println(result);
} catch (ArithmeticException e) {
System.out.println("捕获异常: " + e.getMessage());
e.printStackTrace(); // 打印堆栈跟踪
}
}
private static int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("除数不能为零");
}
return a / b;
}
}
2. 自定义异常
// 自定义业务异常(Checked Exception)
class PaymentFailedException extends Exception {
public PaymentFailedException(String message) {
super(message);
}
public PaymentFailedException(String message, Throwable cause) {
super(message, cause);
}
}
public class PaymentService {
public void processPayment() throws PaymentFailedException {
try {
// 模拟支付失败(如网络异常)
throw new IOException("连接超时");
} catch (IOException e) {
throw new PaymentFailedException("支付失败", e); // 封装底层异常
}
}
}
3. 异常链与资源清理(Java 7+)
public class ResourceDemo {
public static void main(String[] args) {
// try-with-resources 自动关闭资源
try (FileInputStream fis = new FileInputStream("test.txt")) {
fis.read();
} catch (IOException e) {
Throwable[] suppressed = e.getSuppressed(); // 获取被抑制的异常
System.out.println("主异常: " + e.getMessage());
for (Throwable t : suppressed) {
System.out.println("抑制异常: " + t.getMessage());
}
}
}
}
4. 全局异常处理器
public class GlobalExceptionHandlerDemo {
public static void main(String[] args) {
Thread.setDefaultUncaughtExceptionHandler((thread, throwable) -> {
System.err.println("全局捕获到未处理异常: " + throwable.getMessage());
throwable.printStackTrace();
});
// 触发未捕获异常
new Thread(() -> {
throw new RuntimeException("测试全局异常处理");
}).start();
}
}
5. 多异常捕获(Java 7+)
public class MultiCatchDemo {
public static void main(String[] args) {
try {
Class.forName("com.example.NonExistClass");
new ArrayList<>().get(0); // 可能抛出 IndexOutOfBoundsException
} catch (ClassNotFoundException | IndexOutOfBoundsException e) {
System.out.println("捕获多类型异常: " + e.getClass().getSimpleName());
}
}
}
四、注意事项
1、避免捕获 Throwable:
不要直接捕获 Throwable,因为它会包括 Error(如 OutOfMemoryError),这些错误通常无法恢复。
// 错误示例
try {
// 业务代码
} catch (Throwable t) { // 可能掩盖严重问题
t.printStackTrace();
}
2、Checked vs Unchecked 异常:
- Checked Exception:必须显式处理(
try-catch或throws),用于可预见的错误(如文件不存在)。 - Unchecked Exception(RuntimeException):不强制处理,通常表示编程错误(如空指针)。
3、异常性能开销:
频繁抛出异常会影响性能(涉及堆栈跟踪生成),避免用异常控制正常流程。
4、日志最佳实践:
记录异常时,应同时记录堆栈和上下文信息:
catch (IOException e) {
logger.error("文件操作失败: {}", fileName, e); // 使用占位符避免字符串拼接
}
5、Java 14+ 增强:
Throwable 新增 getStackTrace(int depth) 方法,可获取部分堆栈信息以优化性能。
五、总结
Throwable 是 Java 异常处理的基石,合理使用异常机制能显著提升代码健壮性。关键要点:
- 明确区分
Error(不可恢复)和Exception(可处理)。 - 优先使用具体的异常类型(如
IOException而非通用的Exception)。 - 在框架设计中,通过自定义异常封装领域错误。
- 结合现代 Java 特性(如 try-with-resources、多异常捕获)编写简洁高效的代码。
通过正确使用 Throwable 及其子类,可以构建可维护性强、错误处理清晰的 Java 应用程序。
391

被折叠的 条评论
为什么被折叠?



