Java 常见异常(按「运行时 / 编译时」分类)
Java 异常主要分两大类:运行时异常(RuntimeException) (写代码时编译器不报错,运行才出问题)、编译时异常(Checked Exception)(写代码时编译器就提示必须处理,否则跑不了)。
一、最常遇到的「运行时异常」(新手高频踩坑)
这类异常是代码逻辑或使用不当导致的,编译器不强制处理,但实际开发中必须预判。
| 异常名称 | 通俗解释 | 典型触发场景 | 解决方案 |
|---|---|---|---|
NullPointerException (空指针异常) |
最常见!想操作一个「不存在的对象」(对象是 null) | 1. 调用null对象的方法:String s = null; s.length(); 2. 访问null对象的属性 |
1. 调用方法 / 属性前先判空:if (s != null) { s.length(); } 2. 使用 Optional 类(Java 8+)避免空指针 |
ArrayIndexOutOfBoundsException (数组下标越界) |
访问数组时,下标超出了数组的实际长度 | 数组长度为 5,却访问arr[5](数组下标从 0 开始,最大是 4) |
1. 确保下标范围:for (int i=0; i<arr.length; i++) {...} 2. 避免硬编码下标,用数组长度做限制 |
IndexOutOfBoundsException (集合下标越界) |
和数组越界类似,针对 List/Set 等集合 | List<String> list = new ArrayList<>(); list.get(0);(集合为空,却取第 1 个元素) |
1. 操作集合前判断大小:if (!list.isEmpty()) { list.get(0); } 2. 遍历用增强 for 循环:for (String str : list) {...} |
ClassCastException (类型转换异常) |
强行把一个对象转换成不兼容的类型 | Object obj = "hello"; Integer num = (Integer) obj;(字符串转整数) |
1. 转换前用instanceof判断:if (obj instanceof Integer) { ... } 2. 避免无意义的强制类型转换 |
ArithmeticException (算术异常) |
数学运算出错,最常见是「除以 0」 | int a = 10 / 0; |
1. 计算前判断除数:if (b != 0) { int a = 10 / b; } 2. 捕获异常并提示「除数不能为 0」 |
NumberFormatException (数字格式异常) |
把非数字的字符串转换成数字 | Integer.parseInt("abc");("abc" 不是数字) |
1. 转换前校验字符串格式:用正则判断是否为数字 2. 捕获异常,提示「输入不是有效数字」 |
IllegalArgumentException (非法参数异常) |
给方法传了不符合要求的参数 | 方法要求传正数,却传了负数:public void setAge(int age) { if (age < 0) throw new IllegalArgumentException("年龄不能为负"); } |
1. 方法内部校验参数合法性,不合法则抛异常并说明原因 2. 调用方法前确保参数符合要求 |
二、必须处理的「编译时异常」(编译器强制要求)
这类异常是程序运行时可能遇到的外部问题(比如文件找不到、网络断开),Java 强制要求用try-catch捕获,或用throws声明抛出。
| 异常名称 | 通俗解释 | 典型触发场景 | 解决方案 |
|---|---|---|---|
IOException (IO 异常) |
输入 / 输出操作出错(文件 / 流相关) | 1. 读取不存在的文件:new FileReader("test.txt"); 2. 写入文件时磁盘满了 |
1. 用try-catch捕获:java<br>try {<br> FileReader fr = new FileReader("test.txt");<br>} catch (FileNotFoundException e) {<br> System.out.println("文件找不到:" + e.getMessage());<br>} finally {<br> // 关闭流,释放资源<br>}<br> 2. 或在方法上声明throws IOException |
SQLException (数据库异常) |
操作数据库出错 | 1. 数据库连接失败 2. SQL 语句写错 3. 访问不存在的表 / 字段 | 1. 捕获异常并打印错误信息,排查 SQL / 连接配置 2. 确保数据库服务正常,SQL 语句正确 |
ClassNotFoundException (类找不到异常) |
想加载一个不存在的类 | Class.forName("com.mysql.jdbc.Driver");(没导入 MySQL 驱动包) |
1. 检查类名拼写是否正确 2. 确保依赖包(如 JDBC 驱动)已引入项目 |
InterruptedException (中断异常) |
线程在休眠 / 等待时被中断 | Thread.sleep(1000);(线程休眠时被其他线程中断) |
1. 捕获异常后恢复线程中断状态:Thread.currentThread().interrupt(); 2. 不要忽略该异常,需合理处理线程中断逻辑 |
三、异常处理的核心写法(新手必学)
以处理空指针和文件读取异常为例,给你一个完整的示例代码:
java
运行
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
public class ExceptionDemo {
public static void main(String[] args) {
// 1. 处理运行时异常(空指针)
String str = null;
if (str != null) {
System.out.println(str.length());
} else {
System.out.println("字符串为空,无法获取长度");
}
// 2. 处理编译时异常(文件读取)
FileReader fr = null;
try {
// 尝试执行可能出错的代码
fr = new FileReader("test.txt");
System.out.println("文件读取成功");
} catch (FileNotFoundException e) {
// 捕获特定异常,给出明确提示
System.err.println("错误:找不到test.txt文件");
// 打印异常详细信息(调试用)
e.printStackTrace();
} finally {
// 无论是否出错,最终都会执行(用于释放资源)
try {
if (fr != null) {
fr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
总结
- 运行时异常:多是代码逻辑问题,重点在「预判和避免」(如判空、校验参数),而非单纯捕获;
- 编译时异常 :多是外部环境问题,Java 强制要求处理(
try-catch或throws); - 核心原则:异常处理要「精准」(捕获具体异常,而非全用 Exception),且要给出明确的错误提示,方便排查问题。