Java异常处理核心是确保错误行为可预期、影响可控制、问题可追溯;需分清检查型异常(强制处理)、非检查型异常(入口校验)、Error(不捕获);捕获要具体,禁用空catch;资源用try-with-resources;日志须带业务上下文。

Java 中避免程序因异常意外崩溃,关键不是“拦住所有错误”,而是让错误发生时行为可预期、影响可控制、问题可追溯。崩溃往往源于对异常的误用或忽略,而非异常本身。
分清异常类型,按需处理
Java 异常分三类,处理策略完全不同:
- 检查型异常(如 IOException、SQLException):编译器强制你面对——必须 try-catch 或 throws。它们代表外部不确定性(文件不存在、网络断开),应设计恢复逻辑,比如重试、降级或友好提示
- 非检查型异常(如 NullPointerException、IllegalArgumentException):多由逻辑缺陷或非法输入引发,不应靠 catch 补救,而应在入口校验(如 if (str == null) throw new IllegalArgumentException("参数不能为空"))
- Error(如 OutOfMemoryError、StackOverflowError):JVM 层严重故障,不可恢复,不建议捕获,重点是预防(如调优内存、限制递归深度)
捕获要具体,拒绝笼统 catch
写 catch (Exception e) { } 或 catch (Throwable t) { } 是最危险的习惯——它会掩盖真正的问题,甚至吞掉本该中断程序的致命错误。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 优先捕获具体子类:比如用 catch (FileNotFoundException e) 而不是 catch (IOException e),再单独处理其他 IO 场景
- 对同一段代码可能抛出的多种异常,可用多重 catch(Java 7+):catch (IOException | SQLException e)
- 绝不写空 catch;即使决定忽略某次异常(如缓存刷新失败不影响主流程),也必须加注释说明理由
资源释放必须可靠
文件流、数据库连接、Socket 等未关闭,轻则内存泄漏,重则系统句柄耗尽导致后续请求全部失败。
立即学习“Java免费学习笔记(深入)”;
- 首选 try-with-resources:要求资源类实现 AutoCloseable(InputStream、Connection 等均已实现),语法简洁且 JVM 保证关闭
- 示例:try (FileInputStream fis = new FileInputStream("data.txt"); BufferedReader br = new BufferedReader(new InputStreamReader(fis))) { ... }
- 若需在异常后执行清理(如解锁、重置状态),用 finally;但注意 finally 中也应加 try-catch,防止新异常覆盖原始异常
日志与上下文比堆栈更重要
e.printStackTrace() 只适合本地调试。生产环境必须用日志框架(如 SLF4J)记录,并带上真实业务上下文。
- 记录内容至少包括:异常级别(ERROR)、完整堆栈、发生位置(类+方法+行号)、关键业务参数(如订单ID、用户ID)
- 避免把异常转成 null 返回——调用方无法区分“查不到数据”和“查崩了”
- 自定义业务异常(如 InsufficientBalanceException)建议继承 RuntimeException,封装必要字段(如余额、订单号),便于上层统一处理和前端展示

















