在 java 异常处理中,throwable 是所有错误和异常的超类,而 exception 是 throwable 的直接子类。它们的核心区别在于职责分工:throwable 定义了异常体系的根节点,包含所有可被抛出的对象;exception 则专门用于表示程序可以捕获并处理的异常情况,排除了 jvm 层面的致命错误。

Throwable 的继承结构是怎样的
Throwable 有两个直接子类:Error 和 Exception。Error 代表严重的系统级问题,通常不需要也不应该被捕获;Exception 则是开发者需要关注的重点,它包含了运行时异常和非运行时异常。

public class ThrowableHierarchy {
public static void main(String[] args) {
// 检查 Throwable 的子类
System.out.println("Error is subclass of Throwable: " +
java.lang.reflect.Modifier.isPublic(Error.class.getModifiers()) &&
Throwable.class.isAssignableFrom(Error.class));
System.out.println("Exception is subclass of Throwable: " +
Throwable.class.isAssignableFrom(Exception.class));
// 验证 Exception 不是 Error 的子类
System.out.println("Exception is NOT subclass of Error: " +
!Error.class.isAssignableFrom(Exception.class));
}
}
运行结果确认了 Error 和 Exception 是平级的兄弟关系,都直接继承自 Throwable。
立即学习“Java免费学习笔记(深入)”;
Exception 的分类有哪些
Exception 分为两大类:受检异常(Checked Exceptions)和非受检异常(Unchecked Exceptions)。非受检异常即 RuntimeException 及其子类,编译器不强制要求处理;受检异常则是除 RuntimeException 外的其他 Exception 子类,编译器强制要求捕获或声明抛出。

public class ExceptionClassification {
public static void main(String[] args) {
// 受检异常示例
try {
throw new IOException("File not found");
} catch (IOException e) {
System.out.println("Caught checked exception: " + e.getClass().getSimpleName());
}
// 非受检异常示例
try {
throw new NullPointerException();
} catch (NullPointerException e) {
System.out.println("Caught unchecked exception: " + e.getClass().getSimpleName());
}
// 验证 RuntimeException 是 Exception 的子类
System.out.println("RuntimeException is subclass of Exception: " +
Exception.class.isAssignableFrom(RuntimeException.class));
}
}
该程序展示了两种异常的处理方式差异,受检异常必须显式处理,而非受检异常可以选择性处理。
为什么 Error 不应该被捕获
Error 代表 JVM 无法恢复的严重问题,如内存溢出或栈溢出。捕获 Error 通常没有意义,因为此时 JVM 可能已经处于不稳定状态。最佳实践是让 Error 自然传播,由 JVM 终止程序并输出堆栈跟踪信息。


















