写点什么

你真的知道 Java 里的 Exception 和 Error 有啥不同吗?

作者:秃头小帅oi
  • 2025-09-04
    福建
  • 本文字数:1514 字

    阅读完需:约 5 分钟

那天和小李聊天,他刚面试回来,一脸郁闷:"面试官问我 Exception 和 Error 的区别,我说了半天继承关系,结果他说答得太浅显了。这不都是异常吗,有啥区别?"

我笑了笑,想起自己当年也是这么想的。直到那次生产环境的惨案...

那个让我印象深刻的周五下午

记得那是个普通的周五,我正准备下班,突然运维小哥慌张地跑过来:"系统挂了!用户都在投诉!"

打开监控一看,服务器内存爆了,日志里全是这样的信息:

java.lang.OutOfMemoryError: Java heap space    at java.util.ArrayList.grow(ArrayList.java:267)    at com.example.service.DataProcessor.processLargeData(DataProcessor.java:45)
复制代码

我当时第一反应是用 try-catch 包住这段代码,结果发现根本捕获不到!

try {    // 处理大量数据    List<String> hugeList = new ArrayList<>();    for (int i = 0; i < Integer.MAX_VALUE; i++) {        hugeList.add("data_" + i);    }} catch (Exception e) {    // 这里永远不会执行!    logger.error("处理失败", e);}
复制代码

踩坑瞬间

那一刻我才意识到,OutOfMemoryError 压根不是 Exception,而是 Error!

查了源码才发现,Java 的异常体系是这样的:

  • Throwable(老祖宗)

    Error:系统级错误,程序无法处理

    OutOfMemoryError(内存不足)

    StackOverflowError(栈溢出)

    NoClassDefFoundError(找不到类)

    Exception:程序级异常,可以被处理

    RuntimeException(运行时异常)

    检查异常(编译时必须处理)

真正的区别在哪里?

经过那次事故,我总结了三个本质区别:

1. 处理思路完全不同

Exception 是"可以商量的":

try {    int result = 10 / 0;  // ArithmeticException} catch (ArithmeticException e) {    // 可以优雅处理,比如返回默认值    return -1;}
复制代码

Error 是"不讲道理的",你只能接受现实,最多记录一下:

// Error 一般不建议捕获,但如果非要捕获:try {    recursiveMethod();  // 可能导致 StackOverflowError} catch (Error e) {    // 只能记录,然后程序该挂还是会挂    logger.fatal("系统崩溃", e);    System.exit(1);}
复制代码

2. 产生原因天差地别

3. 影响范围不一样

  • Exception:通常影响单个操作或请求

  • Error:往往影响整个应用甚至 JVM

经验启示

那次生产事故后,我养成了几个习惯:

  1. 监控内存使用:定期检查堆内存、栈深度

  2. 区别对待异常:Exception 用于业务处理,Error 用于系统预警

  3. 谨慎捕获 Error:除非做日志记录,否则不要轻易 catch Error

最重要的是,理解了这个区别后,面对异常时的思考方式完全变了:

  • 遇到 Exception:这个问题我能解决吗?怎么优雅处理?

  • 遇到 Error:系统哪里出问题了?需要扩容还是优化?

写在最后

现在再有人问我 Exception 和 Error 的区别,我不会只说继承关系了。它们就像感冒和骨折的区别:

  • Exception 像感冒,吃点药、休息一下就好了

  • Error 像骨折,得上医院,不处理会要命

下次遇到这个问题,你知道怎么回答了吗?

行业拓展

分享一个面向研发人群使用的前后端分离的低代码软件——JNPF

基于 Java Boot/.Net Core 双引擎,它适配国产化,支持主流数据库和操作系统,提供五十几种高频预制组件,内置了常用的后台管理系统使用场景和实用模版,通过简单的拖拉拽操作,开发者能够高效完成软件开发,提高开发效率,减少代码编写工作。

JNPF 基于 SpringBoot+Vue.js,提供了一个适合所有水平用户的低代码学习平台,无论是有经验的开发者还是编程新手,都可以在这里找到适合自己的学习路径。

此外,JNPF 支持全源码交付,完全支持根据公司、项目需求、业务需求进行二次改造开发或内网部署,具备多角色门户、登录认证、组织管理、角色授权、表单设计、流程设计、页面配置、报表设计、门户配置、代码生成工具等开箱即用的在线服务。

用户头像

摸个鱼,顺便发点有用的东西 2023-06-19 加入

互联网某厂人(重生版)

评论

发布
暂无评论
你真的知道 Java 里的 Exception 和 Error 有啥不同吗?_秃头小帅oi_InfoQ写作社区