在Java里Error和Exception如何区分_Java错误模型说明

发布时间 - 2026-01-31 00:00:00    点击率:
OutOfMemoryError 等 Error 是 JVM 系统级崩溃信号,不应 try-catch,而应排查内存配置、GC 日志或堆 dump;IOException 等已检查异常必须处理,NullPointerException 等未检查异常反映代码逻辑缺陷。

看到 OutOfMemoryError 别急着 try-catch

Java 中所有异常的顶层父类是 Throwable,它只派生出两个子类:ErrorException。关键区别就一句话:程序该不该、能不能处理它Error 是 JVM 自己扛不住的系统级崩溃信号,比如 OutOfMemoryErrorStackOverflowErrorNoClassDefFoundError——它们不是你代码写错了,而是 JVM 运行环境崩了。此时捕获并“吞掉”它,只会让程序带病运行,状态不可知,后续行为更危险。

  • 不要在业务逻辑里写 catch (Error e),哪怕加了日志也毫无意义
  • 如果真想兜底(如监控告警),只能用 Thread.setDefaultUncaughtExceptionHandler 捕获线程级未处理的 Throwable,但不建议恢复执行
  • Error 是编译器完全不管的——你漏写 catch 不会报错,但这恰恰说明它不该出现在你的异常处理链里

IOException 必须处理,NullPointerException 可以(但最好别发生)

Exception 分两类:编译器强制你面对的 已检查异常(Checked Exception),和编译期放过的 未检查异常(Unchecked Exception)。前者代表外部不确定性(文件可能被删、网络可能断开),后者基本等于你代码没写严谨(对象没判空、数组越界、类型强转失败)。

  • IOExceptionSQLException 属于已检查异常:不 try-catch 或不声明 throws,编译直接失败
  • NullPointerExceptionArrayIndexOutOfBoundsExceptionRuntimeException 子类,属于未检查异常:编译通过,但运行时炸了就是你逻辑漏洞
  • 别为了省事把已检查异常全包进 catch (Exception e) 然后 e.printStackTrace() ——这等于放弃错误语义,掩盖真实问题

为什么 throw new Error("xxx") 几乎从不出现?

你几乎不会自己 new Error(...) 抛出错误,因为 Error 的设计意图不是给应用层用的。它是 JVM 在底层资源耗尽或结构损坏时自动抛出的“终止信号”。你自己造一个 Error,既不符合语义,也无法触发 JVM 的保护机制(比如 OOM 时的 GC 尝试或堆 dump)。

  • 自定义错误场景,一律用继承 ExceptionRuntimeException 的子类(如 ValidationExceptionBusinessRuleViolationException
  • 若真要表示“这地方绝不该走到”,用 throw new AssertionError("unreachable") 更合适——它也是 Error 子类,但专用于断言失败,且只在 -ea 启动参数下生效,开发阶段可查,生产默认关闭
  • 强行 throw new OutOfMemoryError() 不会触发内存回收,只是立刻杀死当前线程,毫无实际价值

排查时看堆栈最上面一行是 Error 还是 Exception

线上日志或本地调试遇到崩溃,第一眼盯住堆栈最顶端那行:java.lang.OutOfMemoryError 还是 java.io.FileNotFoundException?这个判断直接决定处理路径:

  • 如果是

    Error 开头:立刻查 JVM 参数(-Xmx 是否过小)、GC 日志、是否有内存泄漏(用 jmap -histo 或 MAT 分析 heap dump)
  • 如果是 Exception 开头:先定位抛出位置,看是外部依赖(DB/HTTP/File)不稳定,还是输入校验缺失,或是并发竞争导致状态不一致
  • 特别注意 NoClassDefFoundError:它名字像 Error,但常因类加载器隔离、依赖版本冲突引起——这其实是可诊断、可修复的“配置问题”,不是真正的系统崩溃
真正难的不是分清 ErrorException,而是在 catch (Exception e) 里,你是否还知道它原本是 SQLException 还是 TimeoutException;在 OutOfMemoryError 日志里,你能否从 java_pid*.hprof 文件里一眼看出哪个对象占了 80% 堆内存。分类只是起点,细节才决定能不能修。


# java  #   # 区别  # java错误  # overflow  # 为什么  # jvm  # 父类  # 子类  # try  # throw  # catch  # Error  # 继承  #   # 线程  # Thread  # 并发  # 对象  # http  # 抛出  # 是在  # 运行环境  # 走到  # 出现在  # 你自己  # 它是  # 错了  # 会让 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  香港服务器网站推广:SEO优化与外贸独立站搭建策略  Laravel distinct去重查询_Laravel Eloquent去重方法  Laravel安装步骤详细教程_Laravel环境搭建指南  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  中山网站制作网页,中山新生登记系统登记流程?  Laravel如何使用Passport实现OAuth2?(完整配置步骤)  如何用JavaScript实现文本编辑器_光标和选区怎么处理  如何构建满足综合性能需求的优质建站方案?  如何在建站宝盒中设置产品搜索功能?  Laravel中的withCount方法怎么高效统计关联模型数量  Laravel怎么使用Collection集合方法_Laravel数组操作高级函数pluck与map【手册】  如何在宝塔面板创建新站点?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何在IIS管理器中快速创建并配置网站?  Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理  Laravel观察者模式如何使用_Laravel Model Observer配置  Android自定义listview布局实现上拉加载下拉刷新功能  ,交易猫的商品怎么发布到网站上去?  常州企业网站制作公司,全国继续教育网怎么登录?  JavaScript中如何操作剪贴板_ClipboardAPI怎么用  高端智能建站公司优选:品牌定制与SEO优化一站式服务  Laravel如何实现数据导出到PDF_Laravel使用snappy生成网页快照PDF【方案】  如何用IIS7快速搭建并优化网站站点?  Laravel怎么配置不同环境的数据库_Laravel本地测试与生产环境动态切换【方法】  linux写shell需要注意的问题(必看)  Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】  高防服务器租用指南:配置选择与快速部署攻略  Laravel怎么在Blade中安全地输出原始HTML内容  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  如何快速打造个性化非模板自助建站?  nginx修改上传文件大小限制的方法  再谈Python中的字符串与字符编码(推荐)  如何快速搭建FTP站点实现文件共享?  javascript基于原型链的继承及call和apply函数用法分析  如何在橙子建站上传落地页?操作指南详解  如何正确选择百度移动适配建站域名?  PHP正则匹配日期和时间(时间戳转换)的实例代码  网站建设整体流程解析,建站其实很容易!  Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  Laravel Blade模板引擎语法_Laravel Blade布局继承用法  移动端脚本框架Hammer.js  零服务器AI建站解决方案:快速部署与云端平台低成本实践  javascript中的try catch异常捕获机制用法分析  Laravel Session怎么存储_Laravel Session驱动配置详解  西安专业网站制作公司有哪些,陕西省建行官方网站?  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  Laravel如何使用Socialite实现第三方登录?(微信/GitHub示例)  Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理  网站制作价目表怎么做,珍爱网婚介费用多少?