您的位置: 首页> Java源码> Java异常处理别再瞎搞了!阿里大神总结的 9 种最佳实践,让你的代码更健壮!

Java异常处理别再瞎搞了!阿里大神总结的 9 种最佳实践,让你的代码更健壮!

时间:2025-09-06 14:15:01 来源:互联网

大家好,我是大华。 昨天被迫帮同事改bug,看到他的代码我差点心梗:

try {
    // 业务代码NN行
} catch (Exception e) {
    e.printStackTrace();
}

这异常处理写得,真是老太太钻被窝——哈哈! 同事还说:“代码能跑就行,要啥自行车啊?”

但问题是,这种写法就像是在代码里埋了颗地雷,说不准什么时候就炸了。 所以这篇文章我把从阿里大神那偷师的9个异常处理分享给大家,保准让你的代码更健壮!

1. 别抓了异常又扔掉!

这种就是抓了异常又不处理的:

// 错误示范
try {
    userService.save(user);
} catch (IOException e) {
    e.printStackTrace(); 
}

正确做法

try {
    userService.save(user);
} catch (IOException e) {
    log.error("保存用户信息失败,用户ID:{}", user.getId(), e);
    throw new BusinessException("保存用户失败,请重试");
}

记日志是为了排查问题,重抛异常是让上游知道到底是哪里出错了!

2. 精确捕获异常

很多新手爱用Exception一把梭:

// 错误示范
try {
    // 各种操作
} catch (Exception e) { // 抓得太宽了
    // 处理异常
}

正确写法

try {
    // 业务代码
} catch (FileNotFoundException e) {
    // 处理文件不存在
} catch (IOException e) {
    // 处理IO问题
} catch (SQLException e) {
    // 处理数据库问题
}

不同的异常不同的处理方式!

3. finally里不要乱写!

这个代码看的让人血压直接升高:

try {
    // 业务代码
    return true;
} finally {
    return false; // 居然在finally里返回!
}

finally里只做清理工作

InputStream input = null;
try {
    input = new FileInputStream("file.txt");
    // 处理文件
} finally {
    if (input != null) {
        try {
            input.close(); // 只做资源清理
        } catch (IOException e) {
            log.warn("关闭流失败", e);
        }
    }
}

4. 抛异常要带上原始信息!

这样抛异常等于没抛:

// 错误示范
try {
    // 代码
} catch (IOException e) {
    throw new BusinessException("操作失败"); // 原始异常信息丢了!
}

应该包装原始异常

try {
    // 代码
} catch (IOException e) {
    throw new BusinessException("文件操作失败", e); // 把e传进去
}

这样堆栈信息才不会断!

5. 别用异常做流程控制!

这是我见过最骚的操作:

// 错误示范
try {
    while (true) {
        // 靠异常跳出循环!
        list.get(index);
        index++;
    }
} catch (IndexOutOfBoundsException e) {
    // 循环结束
}

正确写法

for (String item : list) {
    // 正常循环处理
    // 有问题跳出即可
}
// 或者
for (int i = 0; i < list.size(); i++) {
    // 也是正常的
    // 有问题跳出即可
}

异常处理其实还是很耗性能的,不能啥都用异常来抛出!

6. 自定义异常更有意义!

别老是抛RuntimeException

// 不太好的做法
if (user == null) {
    throw new RuntimeException("用户不存在");
}

自定义异常更清晰

// 先定义业务异常
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

// 使用时
if (user == null) {
    throw new UserNotFoundException("用户ID不存在:" + userId);
}

这样一看就知道是什么问题!

7. 异常信息要能看懂!

这种异常信息看了想冒火:

// 错误示范
throw new Exception("出错啦");
throw new Exception("系统错误");

好的异常信息应该这样

// 好的异常信息应该包含关键信息
throw new ValidationException(
    String.format("用户手机号格式错误:%s,请输入11位数字", phoneNumber)
);

throw class BalanceNotEnoughException(
    String.format("用户余额不足,用户ID:%s,当前余额:%.2f,需要金额:%.2f", 
        userId, currentBalance, requiredAmount)
);

看到异常就知道具体什么问题,bug该怎么修!

8. 别忘了异常的性能!

异常处理是昂贵的,别在频繁调用的地方去使用:

// 常用的数据类型转换(错误示范)
try {
    return Integer.parseInt(str);
} catch (NumberFormatException e) {
    return defaultValue;
}

对于可预见的错误,应该先检查

// 先检查再转换,性能更好
if (str == null || !str.matches("\d+")) {
    return defaultValue;
}
return Integer.parseInt(str);

9. 统一异常处理!

最后一点,也是最重要的一点:统一处理异常。

尽量不要在代码里到处try-catch:

// Controller中的方法
@PostMapping("/create")
public Result createUser(@RequestBody User user) {
    try {
        userService.create(user);
        return Result.success();
    } catch (UserExistException e) {
        log.warn("用户已存在", e);
        return Result.error("用户已存在");
    } catch (Exception e) {
        log.error("创建用户失败", e);
        return Result.error("系统繁忙");
    }
}

用@ControllerAdvice统一处理

@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public Result handleBusinessException(BusinessException e) {
        log.warn("业务异常", e);
        return Result.error(e.getMessage());
    }
    
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result handleException(Exception e) {
        log.error("系统异常", e);
        return Result.error("系统繁忙,请稍后重试");
    }
}

这样代码清爽多了,异常处理逻辑都在一起!

总结一下

好的异常处理不是炫技,而是让你的代码:

这9条,不是为了看起来专业,而是为了:线上出问题时,你能第一时间定位,而不是在那干瞪眼。 把这 9 条做成团队规范,省下的不只是时间,还有头发。 —— 写给每一个被异常坑过的 Java 程序员

?往期精彩

《Elasticsearch 太重?来看看这个轻量级的替代品 Manticore Search》

《只会写 Mapper 就敢说会 MyBatis?面试官:原理都没懂》

《别学23种了!Java项目中最常用的6个设计模式,附案例》

《写给小公司前端的 UI 规范:别让页面丑得自己都看不下去》

《Vue3+TS设计模式:5个真实场景让你代码更优雅》

上一篇:深入探索 Java 栈 下一篇:Stream API:mapToInt()使用

相关文章

相关应用

最近更新