核心区别在于编译器是否强制处理:throw new exception必须try-catch或throws,否则编译报错;throw new runtimeexception无需强制处理,可直接通过编译。

Java中 throw new Exception 和 throw new RuntimeException 的核心区别在于编译器是否强制要求处理——前者必须显式处理,后者可以不处理。
编译时是否报错
当你写 throw new Exception("xxx"),编译器会立刻报错:“Unhandled exception”,除非你:
- 用
try-catch包住这行代码 - 或在当前方法声明里加
throws Exception
而 throw new RuntimeException("xxx") 不会触发编译错误,哪怕方法没声明、也没 try-catch,也能直接通过编译。
该用哪个,看异常性质
选 Exception(检查型异常)当问题可预期、应由调用方主动应对:
- 文件读取失败(
IOException) - 数据库连接中断(
SQLException) - 网络请求超时(需重试或提示用户)
选 RuntimeException(非检查型异常)当问题属于程序逻辑缺陷或不可恢复的运行时错误:
- 空指针(
NullPointerException) - 数组越界(
ArrayIndexOutOfBoundsException) - 业务参数非法(如年龄传负数、手机号格式不对)
自定义异常怎么选父类
如果希望调用者“不得不”处理这个异常,继承 Exception;如果只是想快速中断流程并记录日志,继承 RuntimeException 更轻量。
-
class InvalidOrderException extends Exception→ 强制上游校验订单状态 -
class LoginFailedException extends RuntimeException→ 登录失败通常走全局异常处理器,不打断接口调用链
实际开发中的倾向
现代 Java 项目(尤其 Spring Boot)普遍倾向少用检查型异常。因为:
- 层层
throws容易污染方法签名 - 很多“可恢复”的异常最终也只记录日志+返回友好提示
- 统一用
@ControllerAdvice捕获RuntimeException子类更简洁
所以多数业务异常(如余额不足、权限拒绝)都继承 RuntimeException,仅保留极少数真正需要调用方决策的场景才用 Exception。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











