java异常处理防坑指南直击真实痛点:别用try-catch包裹一切,检查型异常必须显式处理或throws;运行时异常应靠校验而非捕获;future.get()需区分interruptedexception(恢复中断)、executionexception(取e.getcause)和cancellationexception(降级);completablefuture链式调用中异常会静默消失,须用exceptionally/handle/whencomplete兜底;npe本质是契约断裂,应以optional、objects.requirenonnull、空集合工具主动防御。

写Java异常处理防坑指南,核心是直击开发者真实踩过的坑,不讲泛泛而谈的理论,只说“哪里会崩”“为什么崩”“怎么改”。重点不是罗列所有异常类型,而是聚焦高频、隐蔽、后果严重的错误模式。
别用 try-catch 包裹一切
很多新手一见红色报错就套 try-catch,结果把原始异常吞掉,日志里只剩 vague 的 “Exception occurred”,根本没法定位。关键不是“捕获”,而是“决策”:
- 检查型异常(如 IOException)必须处理——要么 try-catch 显式兜底,要么向上 throws 声明责任
- 运行时异常(如 NullPointerException、IllegalArgumentException)不该靠 catch 挽救,而应提前校验、防御式编程
- catch 后务必记录完整堆栈:用 e.printStackTrace() 是调试阶段权宜之计;生产环境必须用 logger.error("业务描述", e)
Future.get() 的三种异常不能混为一谈
调用 get() 看似简单,实则藏着三个不同性质的异常,处理方式完全不同:
- InterruptedException:线程被中断——要立即恢复中断状态:Thread.currentThread().interrupt(),否则上层无法感知中断意图
- ExecutionException:任务内部出错——必须调用 e.getCause() 拿到原始异常,否则永远看不到真正报错位置
- CancellationException:任务被取消——说明流程已主动终止,通常无需重试,应转向清理或降级逻辑
CompletableFuture 链式调用中异常会静默消失
这是最易被忽视的坑:用 thenApply 或 thenAccept 处理结果,一旦上游抛异常,整个链就断了,后续回调不执行,也没有报错日志。
- 需要兜底返回值 → 用 exceptionally(Function
) - 需要统一处理成功/失败 → 用 handle(BiFunction
) - 仅做日志或监控,不改变结果 → 用 whenComplete(BiConsumer
)
空指针不是“运气不好”,是设计漏洞
NullPointerException 本质是契约断裂:方法声明返回 String,却可能返回 null;参数声明为 User,却传入 null。防御不能只靠 if (obj != null):
- 对外 API 返回值,优先用 Optional
明确表达“可能为空” - 方法入参校验,用 Objects.requireNonNull(obj, "msg") 在入口处快速失败
- 集合操作前先判空,但更推荐用 CollectionUtils.isEmpty(list)(Apache Commons)或 List.of() 替代可能为 null 的 list
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











