目录
[二、为什么不能只在 catch 里写错误信息?](#二、为什么不能只在 catch 里写错误信息?)
[三、为什么要自定义异常 + throw?](#三、为什么要自定义异常 + throw?)
[为什么要【自定义异常】而不是直接抛 Exception?](#为什么要【自定义异常】而不是直接抛 Exception?)
问题
异常可以直接捕获处理,为什么还要自定义异常,并且用 throw 抛出去?
一、核心区别
-
直接 try-catch 捕获:自己处理异常,异常被 "吃掉",上层调用者不知道出错,方法会继续往下执行。
-
throw 抛出异常:主动触发异常,中断当前方法流程,把异常交给上层去处理。
二、为什么不能只在 catch 里写错误信息?
-
无法中断流程
有些错误必须停止后续逻辑(如余额不足、用户不存在),不能假装正常继续执行。
-
上层无法感知错误
当场捕获处理后,调用方不知道方法执行失败,会导致业务逻辑错乱。
-
错误无法分类
只用通用 Exception,上层只能通过字符串判断错误,不规范、不可靠。
三、为什么要自定义异常 + throw?
-
语义更清晰
系统自带异常无法表达业务错误(余额不足、权限不足、参数非法等)。
-
方便上层精准捕获
可以根据不同异常类型返回不同状态码(400、403、404 等)。
-
符合分层架构
-
Service 层只负责抛出异常
-
Controller / 全局异常处理器统一处理并返回前端
-
职责分离,代码更规范
-
四、代码示例
为什么要【自定义异常】而不是直接抛 Exception?
这才是重点!
你说:我 catch 里也能写错误信息啊。
但问题是:错误类型无法区分!
直接抛 Exception 或 RuntimeException:
java
throw new Exception("余额不足");
throw new Exception("用户名不存在");
throw new Exception("权限不足");
上层 catch 时:
java
try {
} catch (Exception e) {
// 我怎么知道这是余额不足?还是权限不足?
// 只能看消息字符串!非常脆弱!
}
自定义异常 = 给错误 "分类"
java
throw new BalanceNotEnoughException("余额不足");
throw new UserNotFoundException("用户不存在");
throw new PermissionDeniedException("权限不足");
上层可以精准捕获:
java
try {
} catch (UserNotFoundException e) {
// 返回 404
} catch (BalanceNotEnoughException e) {
// 返回 400
} catch (PermissionDeniedException e) {
// 返回 403
}
这才是企业级项目的规范。
强制中断错误流程
throw 后方法立即停止,避免脏逻辑继续执行。
五、一句话总结
-
自定义异常:定义错误类型,让错误有明确业务含义。
-
throw:真正触发异常,把错误交给上层,中断错误流程。
-
只捕获不抛出,会隐藏错误、无法分类、破坏业务流程。