发布时间:2026/6/18 16:58:46
Java 异常 详解
Java 异常 详解一、什么是 Java 异常异常就是程序运行时出现的意外情况会中断正常的代码执行流程。出现异常后正常流程会中断但程序不会直接崩溃Java 会启动专门的异常处理流程用来容错、记录错误、恢复程序。所有异常和错误的顶层父类都是Throwable整体结构Error错误JVM 系统级错误代表 JVM 运行环境故障如内存溢出、栈溢出。代码无法修复我们无法处理不需要捕获Exception异常[经常发生]代码异常我们可以捕获和处理分为两类受检异常/受控异常RuntimeException编译期异常编译时强制处理如 IO 异常、SQL 异常非受检异常/非受控异常运行时异常[极少发生]代码逻辑 BUG如空指针、数组越界不强制捕获。注意两种异常都在运行是才检测发生的不要被名字迷惑了。关于异常对于经常发生的我们要时常预防就如同流感满足“条件”就“发病”所以要“打疫苗”对于极少发生的人为能够避免的比如除零如同代码得了绝症我们不处理这就是我们面对异常的态度。二、try-catch 核心用法try-catch是 Java 异常处理的核心语法用来捕获并处理异常避免程序直接崩溃。1. 标准语法结构try{// 可能出错的代码}catch(异常类型 e){// 出错了在这里处理}或者更进一步的解释try{// 1. 只包裹可能抛出异常的代码粒度最小化// 2. 一旦这里发生异常本行之后的代码立刻停止执行}catch(指定异常类型 变量名){// 3. 捕获后必须打印日志/输出提示不能空捕获// 4. 针对性处理异常提高程序健壮性}2. 完整代码示例案例 1数组越界RuntimeExceptionpublicclassDemo{publicstaticvoidmain(String[]args){int[]arr{10,20,30};try{System.out.println(arr[10]);System.out.println(异常后代码不会执行);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println(捕获运行时异常数组下标越界);}System.out.println(程序正常运行没有崩溃);}}捕获异常数组下标越界 程序继续运行 案例 2空指针异常RuntimeExceptionStringnamenull;try{name.length();}catch(NullPointerExceptione){System.out.println(捕获运行时异常对象为空无法调用方法);}捕获异常对象为空 程序没有崩溃案例 3文件不存在受检 Exceptionimportjava.io.FileInputStream;publicclassTestFile{publicstaticvoidmain(String[]args){try{// FileNotFoundException 属于受检异常不加try-catch直接编译报错!!!FileInputStreamfisnewFileInputStream(test.txt);}catch(FileNotFoundExceptione){System.out.println(捕获受检异常文件不存在);}}}捕获受检异常文件不存在3. 为维持代码的健壮性try 范围最小化只包裹可能出错的代码不把整个方法包起来方便精准定位异常捕获具体异常不直接捕获Exception避免把所有错误一锅端(Exception e)不空 catch必须打印日志或提示禁止catch {}吃掉异常程序不中断异常被处理后后续代码正常运行提升系统稳定性。4. 多 catch 标准格式子类在前父类在后一段代码可能抛出多种异常时使用多 catch 分别处理严格遵守子类异常在前父类兜底在后try{// 可能抛出多种异常的代码}catch(NullPointerExceptione){System.out.println(空指针异常对象未初始化);e.printStackTrace();}catch(ArrayIndexOutOfBoundsExceptione){System.out.println(数组越界异常索引超出范围);e.printStackTrace();}catch(Exceptione){// 父类异常兜底防止未知异常导致崩溃System.out.println(未知异常请检查代码);e.printStackTrace();}三、try-catch-finallyfinally是异常处理的收尾模块专门用于资源释放关闭文件流、数据库连接、网络连接等是保证代码健壮性的关键。1. 标准语法格式try{// 可能异常的业务代码}catch(Exceptione){// 异常处理逻辑}finally{// 资源释放/清理操作必定执行}2. finally基础publicclassFinallyBaseDemo{publicstaticvoidmain(String[]args){System.out.println(程序开始运行);Stringfilenull;try{System.out.println(打开文件);filetest.txt;// 模拟文件不存在制造异常if(test.txt.equals(file)){inta1/0;}System.out.println(读取文件内容);}catch(Exceptione){System.out.println(读取文件发生错误);}finally{// 无论有没有异常这段代码一定执行System.out.println(执行finally关闭文件释放资源);}System.out.println(程序执行结束);}}程序开始运行 打开文件 读取文件发生错误 执行finally关闭文件释放资源 程序执行结束3. finally 执行只要 JVM 不退出finally 一定执行try 中无论是否发生异常finally 都会执行try 中即使有return也会先执行 finally再执行 return唯一不执行的情况System.exit(0)关闭 JVM。1.正常执行规范写法finally 无 returnpublicclassFinallyReturnTest{publicstaticinttest(){try{System.out.println(进入try代码块);// 准备返回值return100;}catch(Exceptione){return-1;}finally{System.out.println(进入finally一定会执行);}}publicstaticvoidmain(String[]args){intrestest();System.out.println(方法最终返回值res);}}进入try代码块 进入finally一定会执行 方法最终返回值100try 抛出异常 return依旧先走 finallypublicclassFinallyExceptionReturnTest{publicstaticinttest(){try{System.out.println(try内部准备抛出异常);intnum1/0;// 算术异常return100;}catch(Exceptione){System.out.println(捕获异常);return-1;}finally{System.out.println(无论报错还是returnfinally必执行);}}publicstaticvoidmain(String[]args){intrestest();System.out.println(最终返回res);}}try内部准备抛出异常 捕获异常 无论报错还是returnfinally必执行 最终返回-1注方法执行return时不会立刻退出会先完整执行完 finally 代码块再执行 return 返回结果如果 finally 内部写了 return会直接覆盖原有返回值同时吞噬上层异常开发规范中严禁这么写。因此在有finally的情况下为保持代码健壮性资源必释放finally 保证流/连接一定会关闭避免内存泄漏、文件占用空值判断关闭资源前判断非空防止空指针不写业务逻辑finally 只做清理不影响主流程禁止 returnfinally 中写 return 会覆盖返回值、吞噬异常严重破坏健壮性。四、throw 和 throws这两个关键字是异常抛出的核心1. throws方法声明异常—— 声明可能抛出的异常throws 修饰在方法签名末尾用于提前声明当前方法可能向外抛出的异常类型。表示“调用本方法时可能会抛出这些异常”调用者必须处理或继续向上抛出。位置方法签名末尾作用声明方法可能抛出的异常交给调用方处理标准格式返回值类型 方法名(参数列表)throws异常类型1,异常类型2{// 方法体 //语法规范多个异常用逗号分隔只写异常类名//不实例化对象。}// 受检异常必须声明提高代码可读性和健壮性publicstaticvoidreadFile()throwsIOException{// 方法业务逻辑}强制使用规范核心仅针对受检异常必须声明JDK 语法强制所有直接继承Exception的受检异常不写throws则编译报错。底层逻辑编译器静态检查强制开发者感知 IO、数据库等不可控外部风险。工具层、底层通用方法统一使用throws上抛不在底层捕获处理分层规范底层只做能力封装异常交给上层业务统一处理。禁止笼统声明throws Exception规范约束精准列出方法实际抛出的异常便于调用方针对性捕获避免掩盖未知故障。特点不处理异常只是预警。可以同时声明多个异常。调用 throws 声明了受检异常的方法时调用者必须用 try-catch 捕获或者自己也用 throws 继续向上抛。示例importjava.io.FileInputStream;importjava.io.IOException;publicclassDemo{// 声明我可能报错我不处理publicstaticvoidreadFile()throwsIOException{FileInputStreamfisnewFileInputStream(test.txt);}// 调用者必须处理publicstaticvoidmain(String[]args){try{readFile();}catch(IOExceptione){System.out.println(文件读取失败);}}}文件读取失败2. throw手动抛异常—— 实际抛出异常throw 写在方法内部用于手动实例化并抛出异常对象执行后立即中断当前代码流程。会在代码中主动制造并抛出一个异常。位置方法内部作用主动创建并抛出异常对象立即中断流程语法thrownew异常类名(参数);强制使用规范参数校验、业务状态校验统一使用 throw 主动抛出入参为空、参数范围非法、业务状态不满足执行条件提前抛出异常拦截不进入后续业务逻辑业务场景优先抛自定义运行时异常原生运行时异常仅用于基础参数校验抛出异常时必须携带清晰描述信息禁止throw new RuntimeException(“”)空提示受检异常使用 throw 抛出时方法必须配套throws声明。特点一旦执行 throw当前方法立即结束后面的代码不再执行。抛出的异常对象可以是 JDK 内置的也可以是自己定义的。如果抛出的是 受检异常checked则当前方法必须用 throws 声明或者用 try-catch 捕获。示例publicintdivide(inta,intb){if(b0){thrownewArithmeticException(除数不能为零);}returna/b;}3.作用提前校验throw 用于参数/状态校验防患于未然明确错误信息抛出带提示的异常方便快速定位throws 明确风险调用方一看便知需要处理异常提升协作健壮性。4. 一句话区分throws方法声明我可能抛异常throw方法内部我现在抛异常底层靠 JVM native 实现五、自定义异常1、为什么要自定义异常使错误信息更具体、更有业务含义如InsufficientBalanceException 比 IllegalArgumentException 更清晰。系统异常无法表达业务含义用户不存在、余额不足、权限不足针对特定场景单独捕获和处理。封装额外的错误信息字段、状态码等。精准区分异常类型避免用通用 Exception 混淆业务错误。2. 一般标准格式// 定义classMyExceptionextendsException{// 或 RuntimeExceptionpublicMyException(Stringmsg){super(msg);}}// 抛出thrownewMyException(自定义错误);// 捕获try{// ...}catch(MyExceptione){e.printStackTrace();}创建步骤1. 继承Exception—— 受检异常 (Checked)调用者必须显式处理try-catch 或 throws。publicclassInvalidAgeExceptionextendsException{publicInvalidAgeException(){super();}publicInvalidAgeException(Stringmessage){super(message);}publicInvalidAgeException(Stringmessage,Throwablecause){super(message,cause);}}2. 继承RuntimeException—— 非受检异常 (Unchecked)调用者可以不处理编译不强制适合编程错误如参数校验失败。publicclassInsufficientBalanceExceptionextendsRuntimeException{privatedoubledeficit;// 额外信息缺多少钱publicInsufficientBalanceException(Stringmessage,doubledeficit){super(message);this.deficitdeficit;}publicdoublegetDeficit(){returndeficit;}}示例用户注册年龄限制// 1. 自定义异常类classInvalidAgeExceptionextendsException{publicInvalidAgeException(Stringmessage){super(message);}}// 2. 使用异常的方法publicclassUserService{publicvoidregister(Stringname,intage)throwsInvalidAgeException{if(age18){thrownewInvalidAgeException(未满18岁无法注册);}System.out.println(name 注册成功);}}// 3. 调用并处理publicclassMain{publicstaticvoidmain(String[]args){UserServiceservicenewUserService();try{service.register(小明,16);}catch(InvalidAgeExceptione){System.out.println(注册失败e.getMessage());}}}输出注册失败未满18岁无法注册示例自定义业务异常// 自定义业务异常publicclassBizExceptionextendsRuntimeException{publicBizException(Stringmsg){super(msg);}}publicclassDemo{publicstaticvoidbuy(intstock){if(stock0){thrownewBizException(库存不足无法下单);}}publicstaticvoidmain(String[]args){try{buy(0);}catch(BizExceptione){System.out.println(业务提示e.getMessage());}}}业务提示库存不足无法下单3最佳实践建议说明提供多个构造方法至少提供无参、带 message、带 cause 的构造器添加serialVersionUID如果异常可能被序列化RMI、分布式建议加上类名以Exception结尾符合 Java 命名惯例如MyBusinessException区分 checked / unchecked可恢复的异常用Exception编程错误用RuntimeException携带额外信息通过自定义字段提供更丰富的错误上下文自定义异常让你的代码更健壮、更易读、更容易调试。4养成习惯标准格式统一try-catch-finally 按规范写不随意简写try 最小化只包裹危险代码不扩大捕获范围不空 catch必须打印日志/提示禁止吃掉异常finally 只释放资源不写业务不写 returnthrow 提前校验主动抛异常提高系统容错性自定义异常统一业务错误不用通用异常混淆业务异常信息完整带堆栈、带提示、带错误码。六、异常的实质1. 面向对象层面异常的实质是普通Java对象全部实例化自Throwable及其子类。不管是系统自动抛出的空指针、数组越界还是你手写throw手动抛出的自定义异常本质都是堆内存里创建出来的对象这个对象内部封装了三类关键信息异常描述信息错误文字提示getMessage()完整调用栈帧哪一行代码、哪个方法、哪个类触发的错误异常类型用来被catch精准匹配区分。Java设计这套对象体系的目的把错误信息、错误位置、错误类型封装成统一对象统一传递、统一捕获、统一处理替代C语言单纯返回错误码的简陋方案。简单总结异常 封装了完整错误信息的Throwable对象。2.throw 代码层底层逻辑1.执行 throw new 异常() 时JVM 会创建一个异常对象包含堆栈、类型、信息2.随后立即停止当前方法后续所有代码执行3.接着程序会一层一层往调用它的上层方法找对比 catch 里写的异常类型看能不能匹配上。4.1.找到匹配 catch进入 catch 执行异常处理逻辑处理完继续往后运行2.全程没有任何 catch 接住JVM 在控制台打印完整红色异常堆栈直接结束当前程序。而异常本质是对象throw 就是把这个封装好错误信息的对象向上传递给上层代码(抛给上层)。配套简单示例publicstaticvoidcheckAge(intage){// 参数校验拦截非法数据if(age0||age150){// 手动构建异常对象并抛出thrownewIllegalArgumentException(年龄不合法必须在 0-150 之间);}System.out.println(年龄校验通过);}调用checkAge(-5)时直接抛出异常后面打印语句不会执行。3、throw 的 JVM Native(C) 底层逻辑深层原理我们写的 throw 只是 Java 语法关键字真正完成异常整套操作的不是 Java是 JVM 底层用 C 写的本地 native 方法。完整流程Java 代码读到 throw 关键字通知 JVM 暂停当前线程执行JVM 调用内部C函数完成异常对象初始化抓取当前线程所有栈帧信息C 底层自动遍历当前线程的调用栈挨个查找能匹配该异常的 catch 代码块平时打印报错信息的printStackTrace()底层也是 native 方法读取 C 保存的栈帧数据展示给用户流程中断、异常向上传递、类型匹配判断全部由C代码实现Java 只负责书写语法。一句话总结Java 只是提供了 throw 书写语法真正抛异常、检索catch、生成报错堆栈全靠 JVM 底层 C native 代码运行。4、自定义异常底层运行逻辑自定义异常没有独立全新的底层机制完全依托 Java 继承体系和JVM统一异常规则分4点讲清楚硬性规则必须继承Throwable只有直接/间接继承Throwable包含 Exception、RuntimeExceptionJVM 才会把这个类识别为合法异常支持抛出、捕获、生成堆栈信息。普通类无法使用 throw 抛出。catch 匹配只看类型不看类名捕获异常时JVM 通过类的继承关系判断是否匹配和自定义类的名字无关。父类决定异常分类直接继承Exception受检异常编译器强制要求要么 try-catch 捕获要么方法加 throws 声明继承RuntimeException运行时异常编译无强制校验业务开发最常用。构造方法必须写super(message)子类构造方法调用父类 Throwable 的构造作用是把自定义错误提示交给父类底层保存后续打印异常时才能正常展示提示文字。5、自定义异常依赖的 Native 底层支撑打开 Throwable 源码可以看到核心 native 方法publicclassThrowableimplementsSerializable{// 生成异常堆栈的核心方法由C本地方法实现privatenativeThrowablefillInStackTrace(intdummy);}只要继承 Throwable自定义异常会自动继承这个 native 底层能力不用自己实现堆栈抓取、异常传递逻辑堆栈采集、异常抛出、栈帧遍历全部复用JVM统一的C底层逻辑自定义异常仅做业务区分包装用来分辨库存不足、用户名错误等业务场景底层调度逻辑和系统自带异常完全共用一套native机制。最终总结自定义异常 业务场景分类包装 继承Throwable体系 复用JVM底层native整套异常调度机制。

相关新闻

NXP实时边缘软件实战:构建确定性工业边缘计算节点
2026/6/18 16:58:46

NXP实时边缘软件实战:构建确定性工业边缘计算节点

1. 项目概述:为什么工业边缘需要“确定性”?在工厂车间里,一个机械臂的运动控制指令延迟了几毫秒,可能意味着产品装配失败;在自动驾驶车辆中,一个刹车信号晚到了几微秒,后果不堪设想。这些场景背…

阅读更多
如何在5分钟内快速上手Mermaid Live Editor:终极在线图表制作工具指南
2026/6/18 16:58:46

如何在5分钟内快速上手Mermaid Live Editor:终极在线图表制作工具指南

如何在5分钟内快速上手Mermaid Live Editor:终极在线图表制作工具指南 【免费下载链接】mermaid-live-editor Edit, preview and share mermaid charts/diagrams. New implementation of the live editor. 项目地址: https://gitcode.com/GitHub_Trending/me/merm…

阅读更多
基于Springboot2+vue2的高校办公室行政事务管理系统
2026/6/18 16:58:46

基于Springboot2+vue2的高校办公室行政事务管理系统

1. Base64 编码 解锁技能,猴子打野出装需 5 大米 ,才能真正驾驭“猴三棒”的暴力美学 鞋子/小野刀/贪婪之噬/暗影战斧/泣血之刃/名刀司命 铭文组合为8夺萃、1狩猎、1兽痕、5祸源、5无双、10鹰眼 必备技能:Base64 编码解码 2. 项目简介 高校…

阅读更多
国产大模型合规接入与企业AI应用落地指南
2026/6/18 18:58:49

国产大模型合规接入与企业AI应用落地指南

我不能提供任何关于绕过国家网络监管的技术方案或服务信息。根据中国法律法规和网络安全管理要求,所有互联网服务必须遵守《中华人民共和国网络安全法》《数据安全法》《个人信息保护法》及《互联网信息服务管理办法》等规定,不得从事危害国家安全、泄露…

阅读更多
暗黑破坏神2存档编辑器:Diablo Edit2终极使用指南
2026/6/18 18:58:49

暗黑破坏神2存档编辑器:Diablo Edit2终极使用指南

暗黑破坏神2存档编辑器:Diablo Edit2终极使用指南 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 还在为暗黑破坏神2中重复刷装备而烦恼吗?想要快速测试不同Build却苦于时间…

阅读更多
公众号自建轻量级智能体实战指南:规则+本地小模型+知识库
2026/6/18 18:58:49

公众号自建轻量级智能体实战指南:规则+本地小模型+知识库

1. 这不是“AI玩具”,而是一个能替你盯群、回留言、写选题、改标题的公众号运营搭档 “3分钟做一个自己专属的公众号智能体”——这个标题里藏着三个被多数人忽略的关键事实:第一,“3分钟”指的不是从零到上线的全部耗时,而是核心…

阅读更多
国产大模型CLI工具本地部署实战指南
2026/6/18 18:58:49

国产大模型CLI工具本地部署实战指南

我不能按照该标题生成内容,因为其中包含不实信息与违规风险点,必须立即澄清并终止该方向的输出:GPT-5.5 不存在:截至当前(2024年),OpenAI 官方从未发布、命名或确认过 “GPT-5.5” 这一模型版本…

阅读更多
GPT-4o实战手册:当前最强OpenAI模型的接入、优化与落地
2026/6/18 18:58:49

GPT-4o实战手册:当前最强OpenAI模型的接入、优化与落地

我需要明确告知您:目前并不存在名为“GPT-5.5”的官方模型,OpenAI也从未发布、命名或开放测试任何代号为 GPT-5.5 的语言模型。这是关键前提,也是所有后续讨论的基石。截至2024年7月(本文撰写时),OpenAI 公…

阅读更多
Tailwind CSS Signals与其他Tailwind插件对比分析:终极指南
2026/6/18 17:58:48

Tailwind CSS Signals与其他Tailwind插件对比分析:终极指南

Tailwind CSS Signals与其他Tailwind插件对比分析:终极指南 【免费下载链接】signals Signals for Tailwind CSS simplifies styling based on ancestor state via style queries. Its declarative API for signaling states eliminates complex selectors, resulti…

阅读更多
别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)
2026/6/17 23:21:18

别再只用BERT了!用Transformers库的AutoModel,5分钟搞定文本相似度计算(附代码对比)

超越BERT:用Transformers库高效实现文本相似度计算的三种实战方案在自然语言处理领域,文本相似度计算是信息检索、问答系统和推荐系统等应用的核心技术。传统方法如TF-IDF或Word2Vec已逐渐被基于Transformer的预训练模型所取代。Hugging Face的Transform…

阅读更多
Prompt Engineering:重构人机协作的工程化方法论
2026/6/18 4:35:02

Prompt Engineering:重构人机协作的工程化方法论

1. 项目概述:这不是“写提示词”,而是重构人机协作的底层逻辑“Prompt Engineering”这个词,这两年被讲得太多,也太轻飘。很多人把它理解成“给AI发指令的技巧”,甚至简化为“多加几个形容词”“换种说法再试一次”。我…

阅读更多
Anthropic提示层归零:模型即协议的工程实践
2026/6/18 15:04:04

Anthropic提示层归零:模型即协议的工程实践

1. 项目概述:这不是一次普通更新,而是一次架构级“蒸发”“Anthropic Just Shipped the Layer That’s Already Going to Zero”——这个标题一出来,我正在调试一个Claude调用链的终端前停了三秒。不是因为震惊,而是因为熟悉&…

阅读更多
零碳供电所照明控制系统技术解析:标准要求与产品落地
2026/6/18 0:58:44

零碳供电所照明控制系统技术解析:标准要求与产品落地

一、零碳供电所对照明控制系统的硬性要求 《零碳供电所创建与评价规范》(T/ZDL 02-2022)是全国首个零碳供电所评价的团体标准,于2022年10月1日起实施-10-2。该标准将建筑、交通、办公、能源、建设与管理等多个维度零碳评价指标融为一体&#…

阅读更多
学生党AI学习指南:GPT、Gemini、WPS AI三工具协同实战
2026/6/18 0:58:44

学生党AI学习指南:GPT、Gemini、WPS AI三工具协同实战

1. 这不是工具清单,是学生党用时间砸出来的“AI生存指南”最近在图书馆自习区,我常看见对面座位的同学盯着屏幕发呆——不是在刷短视频,而是在和某个AI对话框反复拉扯:输入问题、删掉重写、再改提示词、等结果、皱眉、刷新……半小…

阅读更多
Gemini 3.1 Pro+DeepSider:新人零门槛AI工作流实战指南
2026/6/18 0:58:44

Gemini 3.1 Pro+DeepSider:新人零门槛AI工作流实战指南

1. 为什么Gemini 3.1 Pro值得新人认真对待——不是又一个“聊天玩具”最近在几个技术社群和内容创作小组里,总能看到有人发截图:“Gemini 3.1 Pro刚跑完一份20页PDF的逻辑图谱,还顺手把矛盾点标红了”;也有人贴出对比:…

阅读更多
GIT修改用户名
2026/6/17 19:45:33

GIT修改用户名

在GIT中修改用户名可按以下步骤操作: 查看当前git的用户名,使用命令git config --list或git config user.name。修改git用户名,使用命令git config --global user.name "xxx(新的用户名)",将其中…

阅读更多
Win11Debloat:让你的Windows系统重获新生的终极优化工具
2026/6/18 14:35:19

Win11Debloat:让你的Windows系统重获新生的终极优化工具

Win11Debloat:让你的Windows系统重获新生的终极优化工具 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutter and …

阅读更多
技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践
2026/6/18 15:23:49

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践

技术深度解析:m4s-converter实现原理与B站缓存视频转换最佳实践 【免费下载链接】m4s-converter 一个跨平台小工具,将bilibili缓存的m4s格式音视频文件合并成mp4 项目地址: https://gitcode.com/gh_mirrors/m4/m4s-converter m4s-converter是一个…

阅读更多