1. 主页 > 大智慧

Java捕获多个异常的最佳实践:避免代码冗余的3种技巧

哎,各位刚入坑Java的兄弟们,你们有没有遇到过这种情况?写个try-catch块,结果catch堆得比汉堡包还高,每个catch块里还都是重复代码。今天咱就唠唠这个让代码变清爽的秘诀——??三招干掉异常处理里的复制粘贴??!

(拍大腿)先整明白个关键问题:??处理多个异常为啥容易代码冗余??? 举个例子,读取文件+解析数据+网络请求三个操作放一起,每个都可能抛出三四种异常,这要是一个个catch下去,代码量直接爆炸!


第一招:多重catch的妙用(Java7+新特性)

??痛点场景??:
假设你要处理IOException和SQLException,但处理逻辑完全一样
冗余写法

java复制
try {
    // 业务代码
} catch (IOException e) {
    logger.error("文件错误");
} catch (SQLException e) {
    logger.error("文件错误"); // 重复的日志!
}

??优雅改造??:

java复制
try {
    // 业务代码
} catch (IOException | SQLException e) { // 竖线符号连接异常类型
    logger.error("文件操作异常", e);
}

??优势对比表??:

处理方式代码行数可维护性
传统多重catch6行?
合并catch语法3行??

注意!??这招只适用于处理逻辑完全相同的场景??,要是不同异常需要特殊处理,可别偷这个懒!


第二招:异常继承树往上抓

很多新手不知道,??异常类型其实有家族关系??!比如FileNotFoundException是IOException的子类。利用这个特性可以精简代码:

??冗余案例??:

java复制
try {
    new FileInputStream("data.xls");
} catch (FileNotFoundException e) {
    System.out.println("文件不存在");
} catch (IOException e) {
    System.out.println("IO异常"); // 永远执行不到!
}

??问题在哪??? 先捕获子类异常,父类catch块就成摆设了。正确姿势应该是:

java复制
try {
    // 文件操作
} catch (IOException e) { // 一网打尽所有子类异常
    if (e instanceof FileNotFoundException) {
        System.out.println("文件迷路了");
    } else {
        System.out.println("其他IO问题");
    }
}

??关键点??:

  • 使用instanceof做类型判断
  • 保留原始异常信息
  • 适合需要部分差异化处理的场景

第三招:自定义异常统一出口

当遇到跨模块异常时,??创建全局异常处理器才是终极方案??。比如在Spring项目里可以这么玩:

??定义通用异常??:

java复制
public class GlobalException extends RuntimeException {
    private String module;  // 所属模块
    private String code;    // 错误码
    
    // 构造方法省略...
}

??统一捕获处理??:

java复制
@ControllerAdvice
public class ExceptionHandler {
    
    @ExceptionHandler(GlobalException.class)
    public ResponseEntity<?> handleException(GlobalException e) {
        // 返回标准错误格式
        return new ErrorResult(e.getCode(), e.getMessage());
    }
}

??业务层用法??:

java复制
try {
    // 业务代码
} catch (SQLException e) {
    throw new GlobalException("数据库模块", "DB_001", e);
} catch (IOException e) {
    throw new GlobalException("文件模块", "FILE_009", e);
}

??三大好处??:

  1. 前端收到统一格式的响应
  2. 错误信息可读性大幅提升
  3. 新增异常类型无需修改全局处理类

个人踩坑忠告

曾经接手过一个老项目,800多行的Service类里塞了26个catch块,每个都单独处理异常。后来用这三招重构,代码量直接砍掉三分之一!但要注意:

  1. ??别滥用统一异常??:支付等核心模块仍需精细处理
  2. ??日志要打原始堆栈??:别只记录自定义异常的消息
  3. ??保持异常信息完整??:重抛异常时务必带上cause参数

记住啊,异常处理就像垃圾分类——该合并的合并,该拆分的拆分,才能既环保(代码简洁)又高效(便于排查)!

本文由嘻道妙招独家原创,未经允许,严禁转载