mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4
635 字
2 分钟
Java异常处理最佳实践
2026-02-09

在线上被空指针异常搞崩过几次之后,我才真正重视起异常处理的最佳实践。以前觉得try-catch一把梭就完事了,后来发现这样写出来的代码不但不好维护,出了问题还找不到根因。这篇文章总结了我踩过的坑和总结出来的规范。

Java异常处理最佳实践#

异常处理的核心原则#

1. 只捕获你能处理的异常#

不要直接 catch (Exception e) 然后打印个日志就完事。如果你不知道怎么处理,就让它往上抛,让上层代码去处理。

// 不好的做法
try {
// ...
} catch (Exception e) {
e.printStackTrace(); // 然后呢?啥也没干
}
// 好的做法
try {
// ...
} catch (IOException e) {
logger.error("IO error", e);
// 进行恢复操作,比如重试
}

2. 捕获具体的异常类型#

别图省事写 catch (Exception e),这样会掩盖真正的错误。

try {
// ...
} catch (FileNotFoundException e) {
logger.error("文件不存在", e);
} catch (IOException e) {
logger.error("IO异常", e);
}

3. 使用try-with-resources#

所有实现了AutoCloseable的资源都应该用try-with-resources自动关闭。

try (InputStream input = new FileInputStream("file.txt");
OutputStream output = new FileOutputStream("output.txt")) {
// 处理输入输出流
} catch (IOException e) {
logger.error("IO error", e);
}

4. 不要忽略异常#

捕获异常后什么都不做,问题会被隐藏,上线后更难排查。

// 千万不要这样
try {
// ...
} catch (Exception e) {
// 什么都不做
}

5. 不要在循环中捕获异常#

异常对象的创建开销很大(要收集堆栈信息),在循环里频繁抛异常性能会急剧下降。

// 不好的做法
for (int i = 0; i < 1000; i++) {
try {
// ...
} catch (Exception e) {
// ...
}
}
// 好的做法
try {
for (int i = 0; i < 1000; i++) {
// ...
}
} catch (Exception e) {
// ...
}

6. 合理使用自定义异常#

业务逻辑相关的错误用自定义异常,让代码更清晰。

public class BusinessException extends RuntimeException {
private int errorCode;
public BusinessException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() { return errorCode; }
}

7. 异常信息要清晰#

抛出异常时带上足够的上下文信息,方便排查问题。

// 不好的做法
throw new NullPointerException();
// 好的做法
throw new IllegalArgumentException("用户ID不能为空,当前值:" + userId);

8. 正确使用异常链#

捕获一个异常抛出另一个异常时,保留原始异常信息。

try {
// ...
} catch (SQLException e) {
throw new BusinessException(500, "数据库操作失败", e);
}

9. 别用异常控制流程#

异常的开销很大,能用条件判断就用条件判断。

// 不好的做法
try {
return array[index];
} catch (ArrayIndexOutOfBoundsException e) {
return -1;
}
// 好的做法
if (index >= 0 && index < array.length) {
return array[index];
}
return -1;

常见陷阱#

  1. 过度使用异常——以前组里有个同事喜欢用异常做流程控制,代码跑得慢不说,出了问题还特别难排查
  2. 忽略异常——捕获了不处理,等于没事找事
  3. 异常信息不清晰——抛出异常时信息太少,无法定位问题
  4. 资源泄漏——不用try-with-resources,忘了在finally里关资源
  5. 不正确的异常链——转换异常时丢了原始异常

💡 实战贴士: 生产环境建议用日志框架(SLF4J + Logback)记录异常,别用 System.oute.printStackTrace()。而且日志级别要分清楚:业务异常用warn,系统异常用error。这样线上看日志的时候,先看error,再看warn,排查效率高很多。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

部分信息可能已经过时

目录