本文你将收获:
图解Java异常分类体系(附记忆口诀)
️ 异常处理的5大核心关键字实战
自定义异常的3种正确姿势(含代码模板)
新手必踩的5个异常处理深坑解析
真实项目中的异常处理最佳实践
"程序不报错才是奇迹,异常处理才是常态" —— 每一位Java开发者的心声 本文将以咖啡店点单系统为场景,带你用最生活化的案例理解Java异常机制。无论你是刚踩过
NullPointerException
坑的新手,还是想系统掌握异常处理的中级开发者,这里都有你需要的干货!
记忆口诀: "Error要命不管,Exception分两半。Runtime代码错,检查异常必须办!"
// 咖啡制作流程
try {
Coffee cup = 咖啡机.制作咖啡(); // 可能抛出咖啡豆不足异常
cup.递送给顾客();
} catch (咖啡豆不足异常 e) {
服务员.补充咖啡豆(); // 捕获处理特定异常
记录日志("咖啡豆不足,已补充");
} catch (Exception e) {
店长.处理紧急情况(e); // 兜底处理其他异常
} finally {
咖啡机.清洁(); // 无论成功失败都要执行
}
❗ 避坑指南:
catch
块顺序必须从具体到宽泛(子类在前)
finally
中避免写return
语句(会吞掉异常!)
// 服务员接单方法
public void 接单(String 咖啡类型) throws 无效订单异常 {
if (!菜单.contains(咖啡类型)) {
throw new 无效订单异常("本店没有" + 咖啡类型); // 主动抛出异常
}
// 正常处理逻辑...
}
// 调用处处理
try {
服务员.接单("珍珠奶茶"); // 本店是咖啡店!
} catch (无效订单异常 e) {
系统.提示(e.getMessage()); // 输出"本店没有珍珠奶茶"
}
核心区别:
throw
:制造异常(动词)
throws
:声明可能抛出的异常(方法签名)
// 咖啡温度过高异常(必须处理)
class 咖啡温度过高异常 extends Exception {
public 咖啡温度过高异常(int 当前温度) {
super("咖啡温度" + 当前温度 + "℃,烫嘴警告!");
}
}
// 使用示例
void 制作拿铁() throws 咖啡温度过高异常 {
if (温度 > 75) {
throw new 咖啡温度过高异常(温度);
}
// 正常制作...
}
// 无效支付方式异常(代码逻辑问题)
class 无效支付方式异常 extends RuntimeException {
public 无效支付方式异常(String 方式) {
super("不支持" + 方式 + "支付,请使用现金或支付宝");
}
}
// 使用示例
void 处理支付(String 方式) {
if (!方式.equals("现金") && !方式.equals("支付宝")) {
throw new 无效支付方式异常(方式); // 无需声明throws
}
// 处理支付...
}
public class 咖啡店 {
public static void main(String[] args) {
try {
顾客 小明 = new 顾客("小明");
咖啡 今日特饮 = 菜单.获取推荐咖啡();
咖啡师.制作咖啡(今日特饮);
收银台.处理支付(小明.选择支付方式("比特币")); // 抛出无效支付方式异常
} catch (咖啡温度过高异常 e) {
System.out.println("温馨提示:" + e.getMessage());
提供冰块();
} catch (无效支付方式异常 e) {
System.out.println("支付失败:" + e.getMessage());
切换支付方式();
} finally {
清理操作台();
System.out.println("=== 本次服务结束 ===");
}
}
}
异常分类:
Error
像绝症,遇到了基本没救(比如内存溢出)
Exception
分两种:
RuntimeException:你的代码有问题!(比如空指针,数组越界)
检查型异常:必须处理!不处理编译不通过(比如文件找不到)
处理原则:
能处理的用try-catch
(比如网络异常重试)
处理不了的用throws
甩锅(但最终要有人接盘)
finally
最适合做清理工作(比如关闭文件)
自定义异常:
要强制处理的继承Exception
代码逻辑问题继承RuntimeException
异常信息要清晰(比如"温度过高:当前80℃,最大75℃")
常见深坑:
catch
块顺序错误导致异常被吞
finally
中写return
覆盖了异常
过度捕获异常(如直接catch Exception)
日志记录:异常务必记录堆栈信息(e.printStackTrace()
只是临时方案)
异常转换:底层异常封装成业务异常再抛出
资源管理:使用try-with-resources替代finally(Java 7+特性)
现在,你已经掌握了Java异常处理的精髓!下次遇到NullPointerException
时,记得先检查对象是否为null,而不是对着屏幕祈祷哦~