受检异常是Java中必须在编译期显式处理的异常,继承自Exception但不继承RuntimeException;典型代表有IOException、SQLException、ParseException等,多由外部环境引发且可恢复;设计目的是强制开发者应对可预期的运行时问题,而非增加负担。
受检异常(Checked Exception)是Java中一类必须在编译期显式处理的异常,它继承自 Exception 类,但**不继承自 RuntimeException**。编译器会强制要求:调用可能抛出受检异常的方法时,要么用 try-catch 捕获,要么在方法签名中用 throws 声明——否则代码无法通过编译。
它们大多代表**外部环境引发的、可预期且可恢复的问题**,不是代码写错了,而是资源不可用、格式不对或通信失败等客观条件导致的。常见类型包括:
FileNotFoundException(文件不存在)、EOFException(读到流末尾)、SocketException
(网络断连)SQLTimeoutException、SQLSyntaxErrorException,出现在JDBC执行SQL时SimpleDateFormat.parse() 解析非法日期字符串时抛出URI 对象时传入格式错误的字符串Class.forName("xxx"))时类路径中找不到该类这不是为了增加开发负担,而是提醒开发者:这类问题大概率会在运行时发生,且往往有合理补救方式。例如:
关键原则是:**不掩盖、不忽略、不裸 throw**。推荐做法:
示例:
public String readConfig(String path) throws IOException {
// 不在这里 catch,因为读配置失败的具体应对策略由调用方决定
return Files.readString(Path.of(path));
}
// 调用处(如 Web 接口)
@GetMapping("/config")
public ResponseEntity getConfig() {
try {
return ResponseEntity.ok(readConfig("app.conf"));
} catch (IOException e) {
log.warn("配置文件读取失败", e);
return ResponseEntity.status(500).body("配置服务暂时不可用");
}
}
如果一个异常本质上反映的是编程错误(比如参数校验失败、状态非法),就该用非受检异常(IllegalArgumentException、IllegalStateException)。强行用受检异常反而会让调用方疲于应付,违背“可恢复”初衷。另外,现代框架(如 Spring)常将部分受检异常(如 SQLException)包装为非受检异常,也是为了简化 API 使用。