面试官:介绍一下 Java 异常!99% 的人都答不全(附异常体系图)

📅 2026/7/14 13:05:21 👁️ 阅读次数 📝 编程学习
面试官:介绍一下 Java 异常!99% 的人都答不全(附异常体系图)

很多 Java 初学者刚接触异常时都会有这样的疑问:

  • 什么是异常(Exception)?
  • 为什么 Java 要设计异常机制?
  • Error 和 Exception 有什么区别?
  • Checked Exception 和 RuntimeException 又是什么?
  • try、catch、finally、throw、throws 到底有什么区别?

本文将用最通俗的方式,把 Java 异常一次讲明白。


一、什么是 Java 异常?

一句话概括:

Java 异常(Exception)是程序运行过程中发生的错误或异常情况,Java 通过异常机制来发现、传递和处理这些错误,避免程序直接崩溃。

例如:

inta=10;intb=0;System.out.println(a/b);

运行结果:

Exception in thread "main" java.lang.ArithmeticException: / by zero

因为除数不能为 0,所以 JVM 抛出了一个ArithmeticException(算术异常)。


二、为什么要有异常?

假设 Java 没有异常机制。

程序运行:

程序运行 ↓ 出现错误 ↓ 程序直接退出

这样用户只能看到程序崩溃。

而 Java 引入异常后:

程序运行 ↓ 发生错误 ↓ 抛出异常 ↓ 程序捕获异常 ↓ 处理错误 ↓ 程序继续运行

例如:

try{intresult=10/0;}catch(Exceptione){System.out.println("出现异常:"+e.getMessage());}System.out.println("程序继续执行");

输出:

出现异常:/ by zero 程序继续执行

可以看到,虽然发生了错误,但程序并没有直接崩溃,而是继续执行后面的代码。

因此,异常机制的目的就是让程序能够优雅地处理错误,提高程序的健壮性。


三、Java 异常体系

Java 中所有异常最终都继承自Throwable

整个继承关系如下:

Throwable / \ Error Exception | ---------------------------- | | Checked Exception RuntimeException (编译时异常) (运行时异常)

可以看到,Java 的异常主要分为两大类:

  • Error(错误)
  • Exception(异常)

其中 Exception 又分为:

  • Checked Exception(编译时异常)
  • RuntimeException(运行时异常)

下面分别介绍。


四、Error(错误)

Error 表示JVM 自身发生了严重错误

例如:

OutOfMemoryError StackOverflowError

举个例子:

publicclassTest{publicstaticvoidtest(){test();}publicstaticvoidmain(String[]args){test();}}

由于方法无限递归调用,最终会出现:

StackOverflowError

Error 的特点

  • JVM 层面的严重错误
  • 一般程序员无法恢复
  • 通常不建议使用 try-catch 捕获

一句话记忆:

Error 是 JVM 的严重错误,一般不用程序去处理。


五、Exception(异常)

Exception 表示程序运行过程中可能发生的问题。

例如:

  • 文件不存在
  • 数据库连接失败
  • 空指针
  • 数组越界

Exception 又分为两类。


1、Checked Exception(编译时异常)

编译器要求必须处理

例如:

FileInputStreamfis=newFileInputStream("a.txt");

编译器直接报错:

Unhandled exception

必须使用:

try{FileInputStreamfis=newFileInputStream("a.txt");}catch(FileNotFoundExceptione){}

或者:

publicvoidread()throwsFileNotFoundException{}

常见编译时异常:

IOException SQLException ClassNotFoundException

一句话:

编译时异常必须处理,否则代码无法通过编译。


2、RuntimeException(运行时异常)

运行时异常编译器不会强制要求处理

例如数组越界:

int[]arr={1,2};System.out.println(arr[5]);

运行结果:

ArrayIndexOutOfBoundsException

再例如空指针:

Stringstr=null;System.out.println(str.length());

运行:

NullPointerException

编译器不会报错。

因为这些异常通常是程序员编写代码时的逻辑错误。

开发中最常见的 RuntimeException 有:

NullPointerException ArithmeticException ArrayIndexOutOfBoundsException ClassCastException NumberFormatException

一句话:

运行时异常一般由程序逻辑错误导致,编译器不强制处理。


六、Error 和 Exception 的区别

ErrorException
JVM 严重错误程序运行异常
一般无法恢复可以处理
不建议捕获可以捕获
例如 OOM例如空指针

记住一句话:

Error 是 JVM 的问题,Exception 是程序的问题。


七、Java 如何处理异常?

Java 提供了五个关键字:

try catch finally throw throws

下面分别介绍。


1、try

放可能发生异常的代码。

try{}

2、catch

捕获异常。

例如:

try{inta=10/0;}catch(ArithmeticExceptione){System.out.println("除数不能为0");}

程序不会崩溃,而是进入catch


3、finally

无论是否发生异常都会执行。

try{}finally{}

通常用于:

  • 关闭数据库连接
  • 关闭文件
  • 释放资源

例如:

try{}finally{connection.close();}

4、throw

主动抛出一个异常对象。

例如:

if(age<0){thrownewIllegalArgumentException("年龄不能小于0");}

这里不是 JVM 自动抛异常,而是程序员主动抛。


5、throws

声明方法可能抛出的异常。

例如:

publicvoidreadFile()throwsIOException{}

表示:

我这个方法可能会抛出 IOException,调用者需要处理。


八、throw 和 throws 的区别(高频面试)

很多初学者容易混淆。

其实很好记:

throwthrows
主动抛异常声明异常
写在方法内部写在方法声明后
后面跟异常对象后面跟异常类型

例如:

thrownewRuntimeException();

表示:

主动抛出一个异常对象。

而:

publicvoidtest()throwsIOException{}

表示:

告诉调用者,这个方法可能抛 IOException。

一句话:

throw 是抛,throws 是声明。


九、最常见的运行时异常

开发中最容易遇到的就是下面几个。

1、NullPointerException(空指针)

Stringstr=null;str.length();

2、ArithmeticException(算术异常)

10/0;

3、ArrayIndexOutOfBoundsException(数组越界)

arr[100];

4、ClassCastException(类型转换异常)

Animalanimal=newAnimal();Dogdog=(Dog)animal;

5、NumberFormatException(数字格式异常)

Integer.parseInt("abc");

十、异常是如何传播的?

假设方法调用关系如下:

main() ↓ A() ↓ B() ↓ C()

如果:

C()

发生异常:

C 不处理 ↓ 抛给 B ↓ B 不处理 ↓ 抛给 A ↓ A 不处理 ↓ 抛给 main ↓ main 不处理 ↓ JVM ↓ 程序结束

这就是异常传播机制

一句话:

异常会沿着方法调用栈一级一级向上传递,直到被处理,否则最终交给 JVM。


十一、面试如何回答?

如果面试官问:

介绍一下 Java 异常。

可以这样回答:

Java 的异常是程序运行过程中出现的异常情况,所有异常都继承自ThrowableThrowable分为ErrorException,其中Error表示 JVM 严重错误,一般不处理;Exception表示程序异常,又分为编译时异常和运行时异常。编译时异常必须处理,运行时异常通常由程序逻辑错误导致,不强制处理。Java 提供try-catch-finallythrowthrows等机制来捕获、抛出和传递异常。

这是一个比较完整且面试官认可度较高的回答。


十二、总结

最后用一张图总结整个异常体系。

Throwable / \ Error Exception | ---------------------------- | | Checked Exception RuntimeException (必须处理) (可不处理) 处理方式: try catch finally throw throws

记住下面四句话即可:

  • Throwable 是所有异常和错误的父类。
  • Error 是 JVM 的严重错误,一般不处理。
  • Exception 是程序异常,分为编译时异常和运行时异常。
  • Java 通过 try-catch、throw、throws 等机制实现异常的捕获、传递和处理。

一句话总结:Java 异常本质上是一套错误处理机制,它将程序运行过程中发生的问题封装成异常对象,通过抛出、传递和捕获异常,让程序能够更加稳定、健壮地运行。