IllegalArgumentException 是开发者主动抛出的运行时异常,用于参数逻辑合法性校验失败,如负数年龄、非法枚举值等;语义上区别于 NullPointerException,后者专用于明确禁止 null 的场景。

IllegalArgumentException 是谁抛的、在哪儿抛的
它不是 JVM 自动抛的,而是开发者主动 throw new IllegalArgumentException() 的结果。常见于方法入口对参数做合法性检查失败时——比如传了 null 却要求非空,传了负数却要求正整数,传了不支持的枚举值,或者字符串格式明显非法(如解析日期时传了 "2023-13-01")。
注意:它属于 unchecked exception(运行时异常),编译器不强制捕获,所以很容易被忽略或漏写校验逻辑。
什么时候该用 IllegalArgumentException 而不是 NullPointerException
核心区别在于语义:如果参数本身是 null 且业务逻辑明确禁止 null,用 NullPointerException 更准确(JDK 自己也这么干,比如 Objects.requireNonNull 抛的就是它);但如果你检查的是值的逻辑合理性(比如 age = -5、mode = "xyz"),那就该用 IllegalArgumentException。
-
Objects.requireNonNull(param, "param must not be null")→ 推荐,抛NullPointerException -
if (age = 0")→ 合理,抛IllegalArgumentException - 混用(比如对
null手动抛IllegalArgumentException)会模糊错误意图,调用方难排查
Spring 中怎么统一拦截并处理 IllegalArgumentException
Spring MVC 提供 @ControllerAdvice + @ExceptionHandler 做全局异常捕获,但要注意:默认不会捕获所有未声明的运行时异常,除非你显式写了对应 handler。
立即学习“Java免费学习笔记(深入)”;
一个最小可用配置:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public ResponseEntity<String> handleIllegalArgument(IllegalArgumentException e) {
return ResponseEntity.badRequest().body("Invalid input: " + e.getMessage());
}
}
- 确保该类被 Spring 扫描到(比如放在主启动类同包或子包下)
- 别忘了加
@ResponseBody或返回@RestControllerAdvice,否则可能走视图解析 - 生产环境建议封装成标准响应体(含 code/message/data),而不是裸字符串
- 它不拦截 Filter 或 Interceptor 中抛出的异常,那些得单独处理
容易被忽略的校验盲区和性能影响
很多人只在校验“明显错”的地方 throw,却漏掉边界情况。比如:
- 集合类参数:传了
null或空集合,但方法内部直接调list.get(0) - 时间类型:
LocalDateTime.parse("2023-01-01")缺少时分秒会抛DateTimeParseException,不是IllegalArgumentException,但语义相同,建议包装后重抛 - 频繁调用的方法(如工具类、DTO 转换)里做复杂校验,可能引入可观的 CPU 开销,尤其在高并发场景
- 日志打太全(比如 dump 整个 request body)可能泄露敏感字段,建议只记录关键参数名和值摘要
校验逻辑越靠近入口越好,但别为了“严谨”在每层都重复校验;接口层收口一次,服务内部信契约即可。










