好的!下面是为0基础小白量身打造的Java异常处理超详细入门教程,尽量用最白话、最生活化的语言来讲清楚,帮助你真正理解并会用异常。
我们把异常分成这几个大块来学(由浅入深):
- 异常到底是什么?(生活比喻最重要!)
- Java异常家族树长啥样?
- 两大阵营:必须处理 vs 可以不处理
- 最常用的处理方式:try-catch-finally
- 方法后面写 throws 是什么意思?
- 我自己制造异常:throw
- 自己发明异常:自定义异常
- 常见面试/实际开发必知点
- 小练习(建议你敲代码)
1. 异常到底是什么?(最重要的一步!)
生活比喻:
你在点外卖,正常流程是:
手机 → 下单 → 商家接单 → 骑手接单 → 送达
但中途可能出现这些“意外情况”:
- 商家已经关门了(相当于文件找不到)
- 余额不足(相当于除以0)
- 骑手在路上摔了,送不了(网络中断、数据库连不上)
- 你输错地址,骑手找不到(输入参数非法)
这些“正常流程被打断的意外情况”,在Java里就叫异常(Exception)。
一句话总结:
程序在运行阶段遇到它无法按照正常逻辑继续往下走的情况,就叫异常。
2. Java异常家族树(记住这张图就够用了)
java.lang.Object
└─ java.lang.Throwable ← 所有异常和错误的祖宗
├─ java.lang.Error ← 严重错误(基本救不回来,程序员通常不处理)
│ ├─ OutOfMemoryError
│ ├─ StackOverflowError
│ └─ ...
└─ java.lang.Exception ← 我们99%时间处理的都是它
├─ RuntimeException(运行时异常/非检查异常)
│ ├─ NullPointerException ← 空指针
│ ├─ ArrayIndexOutOfBoundsException
│ ├─ ArithmeticException ← 除以0
│ ├─ ClassCastException
│ ├─ NumberFormatException
│ └─ ...
└─ 其他(检查异常/受检异常)
├─ IOException
│ ├─ FileNotFoundException
│ └─ ...
├─ SQLException
├─ InterruptedException
└─ ...
最核心记忆口诀:
- Error:天塌了(内存耗尽、栈溢出),基本放弃治疗
- RuntimeException及其子类:程序员的锅(可以不写catch,但最好改代码避免)
- 其他Exception(非RuntimeException的):环境的锅/外界的锅(必须处理,不然编译不通过)
3. 两大阵营对比(超级重要!)
| 特性 | 检查异常(Checked Exception) | 非检查异常(Unchecked Exception) |
|---|---|---|
| 继承自 | Exception 但不是 RuntimeException | RuntimeException 或 Error |
| 是否必须处理 | 必须(编译器强制) | 不必须(编译器不管) |
| 什么时候出现 | 大多是“外部环境”问题 | 大多是“代码逻辑”问题 |
| 典型例子 | IOException、SQLException | NullPointerException、除0、数组越界 |
| 处理方式 | try-catch 或 throws | 尽量避免,实在不行也可以catch |
| 是否要写在方法后面 | 通常要写 throws | 不需要写 throws |
4. 最最最常用的写法:try-catch-finally
最基础结构(记住这个就先能应付80%场景):
try {
// 可能出问题的代码(危险区)
int a = 10 / 0;
System.out.println("这句话不会执行");
} catch (ArithmeticException e) { // 专门抓除0异常
System.out.println("除数不能为0哦~");
e.printStackTrace(); // 打印错误信息(非常推荐)
} catch (Exception e) { // 万能捕获(建议放最后)
System.out.println("其他未知错误");
} finally { // 无论是否出错都会执行(常用来关资源)
System.out.println("我一定会执行!");
}
进阶常用写法(推荐):
try {
// 危险代码
} catch (Exception e) {
// 先记录日志(实际项目必做)
// log.error("用户{}操作失败", userId, e);
// 再给用户友好提示
System.out.println("服务器开小差了,请稍后再试~");
} finally {
// 关闭文件、连接、锁等
}
5. throws 和 throw 的区别(背下来!)
| 关键字 | 位置 | 含义 | 谁用 |
|---|---|---|---|
| throws | 方法声明后面 | “我可能会出这种问题,你调用我的人自己处理吧” | 方法签名上(告诉调用者) |
| throw | 方法体里面 | “现在就出问题了!我主动制造一个异常扔出去!” | 自己new异常然后扔出去 |
// throws 写在方法上(声明我可能会抛出异常)
public void readFile() throws IOException, FileNotFoundException {
// ...
}
// throw 写在方法里面(主动抛)
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数!");
}
6. 自定义异常(面试+实际开发很常见)
// 1. 继承 RuntimeException(推荐,大部分业务异常用这个)
public class BizException extends RuntimeException {
public BizException(String message) {
super(message);
}
public BizException(String message, Throwable cause) {
super(message, cause);
}
}
// 2. 使用
if (money < 0) {
throw new BizException("余额不足,无法扣款!");
}
7. 常见异常一览表(背下来见到就知道怎么回事)
| 异常类 | 中文含义 | 典型场景 | 属于哪类 |
|---|---|---|---|
| NullPointerException | 空指针 | person.getName() 但person是null | 运行时 |
| ArithmeticException | 算术异常 | 10 / 0 | 运行时 |
| ArrayIndexOutOfBoundsException | 数组越界 | int[] a = new int[3]; a[5] | 运行时 |
| ClassCastException | 类型转换异常 | (String) new Integer(1) | 运行时 |
| NumberFormatException | 数字格式异常 | Integer.parseInt(“abc”) | 运行时 |
| FileNotFoundException | 文件找不到 | new FileInputStream(“不存在.txt”) | 检查异常 |
| IOException | 输入输出异常 | 文件读写、网络 | 检查异常 |
| SQLException | 数据库异常 | SQL写错、连不上数据库 | 检查异常 |
最后:给0基础小白的建议路线
- 先记住上面那张异常家族树和两大阵营对比表
- 把try-catch-finally敲10遍以上,换不同异常练手
- 能熟练写出 throw new XXXException(“提示语”)
- 遇到检查异常(红线)就知道要么catch要么throws
- 业务代码中尽量用自定义业务异常而不是直接用Exception
- 实际项目记住:先log异常,再给用户友好提示
你现在最想练哪一部分?
- 想多看几个完整的try-catch例子?
- 想看自定义异常的实战写法?
- 想知道finally和return一起出现时谁先执行?
- 还是想直接来几道小练习题?
告诉我你的需求,我继续陪你打怪升级~ 😄