# Java异常类型
# 简要回答
- Java 中的异常都继承自
java.lang.Throwable类,它分为两大类:Error和Exception。Error(错误) :
表示 JVM 内部 或 系统级别的问题,通常是很严重的,程序无法恢复。例如:OutOfMemoryError(内存溢出)、StackOverflowError(栈溢出)。Exception(异常) :
表示程序在 编译时 或 运行时 可能发生的问题,通常是可捕获和处理的。Exception又分为两大子类:
① 编译期异常 (Checked Exception) :是指编译器强制检查的异常,必须进行try-catch捕获处理 或者throws声明处理,常见的编译期异常有IOException(输入输出异常)、SQLException(数据库操作异常)。
② 运行期异常 (Runtime Exception / Unchecked Exception) :是指编译器不强制检查的异常,通常是程序逻辑错误导致的,可选择性处理,常见的运行期异常有NullPointerException(空指针异常)、ArrayIndexOutOfBoundsException(数组越界异常)。
# 详细回答
- Java 中所有的异常都源于
java.lang.Throwable类,它有两个主要的直接子类:Error和Exception。
Error(错误) :- 定义:
Error类及其子类表示了在 程序运行期间发生的、JVM 或 系统级别的 严重问题,这些问题通常是应用程序无法预料和恢复的。例如,JVM 内存耗尽、JVM 错误、线程死锁等。 - 特点:
Error是非受检查异常 (Unchecked Exception) 的一种特殊形式,编译器不会强制捕获或声明。由于它们通常是致命的,即使捕获了也难以恢复,因此在开发中,通常不会去捕获Error,而是让程序终止,以便系统管理员介入处理。 - 常见类型:
①java.lang.OutOfMemoryError:是指当JVM内存不足,无法分配对象时抛出。
②java.lang.StackOverflowError:是指当方法调用栈溢出时抛出,通常是由于无限递归导致。
③java.lang.NoClassDefFoundError:当JVM试图加载某个类,但在运行时找不到该类的定义时抛出。
④java.lang.VirtualMachineError:虚拟机在运行时发生的内部错误。
- 定义:
Exception(异常) :- 定义:
Exception类及其子类表示程序在运行过程中可能遇到的、可以被捕获和处理的异常情况。这些异常通常是由于外部因素(如文件不存在、网络中断)或程序逻辑错误导致的。 - 特点:
Exception是我们日常开发中主要关注和处理的异常类型。它进一步分为两大类:编译期异常 和 运行期异常。 - 编译期异常 (Checked Exception / 受检查异常) :
- 这类异常是指所有直接或间接继承自
java.lang.Exception,但不是java.lang.RuntimeException及其子类的异常。它们之所以被称为“编译期异常”或“受检查异常”,是因为Java编译器会强制检查你是否对这类异常进行了处理(例如 使用try-catch块捕获,或 使用throws关键字抛出),如果未处理或声明,代码将无法编译通过。 - 编译期异常通常表示程序外部环境可能出现的问题,是可预见的、可恢复的。所以开发者在编写代码时,需要明确地考虑这些异常,并提供相应的处理逻辑。
- 常见类型:
①java.io.IOException:是指所有 I/O操作(如文件读写、网络通信)可能抛出的异常的基类。
②java.io.FileNotFoundException:是指尝试打开一个不存在的文件时抛出的异常。
③java.sql.SQLException:在数据库访问操作中发生的异常。
④java.lang.ClassNotFoundException:是指当应用程序试图通过类的字符串名称加载类,但找不到该类定义时抛出。
⑤java.lang.InterruptedException:当一个线程在等待、休眠或占用途中,被另一个线程中断时抛出。
- 这类异常是指所有直接或间接继承自
- 运行期异常 (RuntimeException / Unchecked Exception / 非受检查异常) :
- 这类异常是
RuntimeException类及其所有子类。它们被称为“运行期异常”或“非受检查异常”,是因为编译器不会强制检查你是否捕获或声明它们,因为即使不处理,代码也能编译通过。 - 运行期异常通常表示程序内部的逻辑错误、编程缺陷或不合法的参数。这类异常通常是由于程序员的疏忽导致的,例如,尝试访问空对象的成员、数组越界等。
- 常见类型:
①java.lang.NullPointerException:是指尝试对一个null对象进行操作时抛出的异常。
②java.lang.ArrayIndexOutOfBoundsException:是指数组索引超出其有效范围时抛出的异常。
③java.lang.ClassCastException:是指在进行强制类型转换时,如果对象不是目标类型的实例,则抛出。
④java.lang.IllegalArgumentException:是指向方法传递了一个不合法或不正确的参数时抛出的异常。
⑤java.lang.NumberFormatException:是指尝试将一个不符合数字格式的字符串转换为数字时抛出的异常。
⑥java.lang.ArithmeticException:是指发生不合法的算术运算时抛出的异常,例如除以零。
⑦java.lang.IndexOutOfBoundsException:是指所有索引超出范围异常的基类(包括数组、字符串、集合等)。
- 这类异常是
- 定义:
# 知识拓展
- Java异常体系图,如下所示:

- 面试官可能的追问1:为什么Java要区分编译期异常和运行期异常?这种设计有什么好处和坏处?
- 简答: 这种区分是Java异常处理的核心设计理念,可以平衡程序的健壮性和开发效率。
① 好处:编译期异常 会强制开发者处理那些外部环境可能导致的问题(如文件不存在、网络中断),使得程序对这些可预见且可能恢复的错误更加健壮。运行期异常通常指示编程错误,不强制处理有助于快速发现和修复这些错误,避免代码中充斥大量无意义的try-catch块。
② 坏处:代码冗余,对于一些不重要的编译期异常,强制处理可能导致代码中出现大量try-catch块,增加代码的冗余度和可读性负担。而且,开发者有时会为了通过编译而捕获所有编译期异常,但可能没有提供有效的处理逻辑,反而掩盖了问题。
- 简答: 这种区分是Java异常处理的核心设计理念,可以平衡程序的健壮性和开发效率。
- 面试官可能的追问2:在实际开发中,我们应该如何选择抛出编译期异常还是运行期异常?
- 简答:
① 当异常是可预见的、可恢复的,并且是由于外部环境或调用者错误导致的,应该抛出编译期异常。这强制调用者处理这些异常,提高程序的健壮性。例如,文件操作、网络连接、数据库访问等。
② 当异常是不可预见的、通常是由于程序逻辑错误或编程缺陷导致的,应该抛出运行期异常。这表明调用者应该在调用前避免这些错误,或者通过更严格的输入校验和边界检查来预防。例如,非法参数(IllegalArgumentException)、空指针(NullPointerException)等。
- 简答:
评论
验证登录状态...