Java 异常处理:别再只会 try-catch 了

举报
Brian-Tony 发表于 2026/10/28 08:49:01 2026/10/28
【摘要】 Java 异常处理:别再只会 try-catch 了写 Java 代码时,异常处理几乎天天见。但很多人对异常的理解还停留在“报错了就 try-catch 包起来”的阶段,结果代码里到处是空的 catch 块,或者一个方法 throws 了十几个异常,读起来让人头大。今天来梳理一下 Java 异常的正确打开方式。 异常体系一览Java 的异常都继承自 Throwable,下面分两大分支:Er...

Java 异常处理:别再只会 try-catch 了

写 Java 代码时,异常处理几乎天天见。但很多人对异常的理解还停留在“报错了就 try-catch 包起来”的阶段,结果代码里到处是空的 catch 块,或者一个方法 throws 了十几个异常,读起来让人头大。今天来梳理一下 Java 异常的正确打开方式。

异常体系一览

Java 的异常都继承自 Throwable,下面分两大分支:

  • Error:JVM 层面的严重问题,比如 OutOfMemoryError、StackOverflowError。这类问题程序通常无法恢复,不用去 catch。
  • Exception:程序可以处理的异常,又分为两类:
    • 受检异常(Checked Exception):编译器强制你处理,比如 IOException、SQLException。要么 try-catch,要么 throws 抛出去。
    • 非受检异常(Unchecked Exception):即 RuntimeException 及其子类,比如 NullPointerException、IndexOutOfBoundsException。编译器不强制处理,但你应该在代码层面避免它们发生。

常见误区

1. catch 块里什么都不写

try {
    doSomething();
} catch (Exception e) {
    // 空的,啥也不干
}

这是最糟糕的做法。异常被"吞掉"了,出了问题根本无从排查。至少要打一行日志:

} catch (Exception e) {
    log.error("操作失败", e);
}

2. 用异常做流程控制

try {
    int value = Integer.parseInt(str);
} catch (NumberFormatException e) {
    // 用异常来判断字符串是不是数字
}

异常处理的性能开销很大,不应该用来替代正常的逻辑判断。

3. 一个 catch 捕获所有异常

try {
    // 一堆操作
} catch (Exception e) {
    // 统一处理
}

不同的异常应该有不同的处理方式。数据库异常可能要回滚事务,IO 异常可能要关闭资源,混在一起处理会丢失针对性。

最佳实践

1. 优先使用 try-with-resources

处理流、连接等资源时,用 try-with-resources 自动关闭,再也不用写烦人的 finally 块:

try (InputStream is = new FileInputStream("file.txt")) {
    // 操作流
} catch (IOException e) {
    log.error("文件读取失败", e);
}

2. 自定义异常要有意义

不要为了"看起来专业"就创建一堆 XXXException。只有当业务上确实需要区分特定错误类型时,才自定义异常:

public class OrderNotFoundException extends RuntimeException {
    public OrderNotFoundException(Long orderId) {
        super("订单不存在: " + orderId);
    }
}

3. 异常信息要包含上下文

// 不好
throw new RuntimeException("操作失败");

// 好
throw new RuntimeException("用户ID=" + userId + " 的订单创建失败", e);

4. 不要在 finally 中 return

try {
    return doSomething();
} finally {
    return; // 会覆盖 try 中的返回值,极其危险
}

一句话总结

  • Error 不用管,Checked Exception 必须处理,Unchecked Exception 应该避免。
  • catch 块里至少要打日志,别吞异常。
  • 资源关闭用 try-with-resources,简洁又安全。
  • 异常是"异常"情况,不要拿来当正常流程控制。

这篇也是经典主题,内容扎实但不会太深,适合水论坛。需要再来一篇"Java 多线程基础"或者"Spring Bean 生命周期"吗?

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。