Java异常体系知识梳理
Java异常体系知识梳理作者没有四次元口袋的蓝胖日期2026-07-10标签Java, 异常, Throwable一、异常体系结构Java 异常体系以Throwable为根类分为两大分支Error和Exception。Throwable ├── Error严重错误程序无法处理 │ ├── OutOfMemoryErrorOOM │ ├── StackOverflowError栈溢出 │ ├── NoClassDefFoundError │ └── LinkageError │ └── Exception异常程序可以处理 ├── RuntimeException运行时异常非受检异常 │ ├── NullPointerExceptionNPE │ ├── ArrayIndexOutOfBoundsException │ ├── ClassCastException │ ├── ArithmeticException │ ├── IllegalArgumentException │ ├── IllegalStateException │ └── UnsupportedOperationException │ └── 其他异常受检异常编译时异常 ├── IOException ├── SQLException ├── ClassNotFoundException └── FileNotFoundException1.1 Error vs Exception对比ErrorException严重程度严重错误程序无法恢复一般异常程序可以处理来源JVM 系统级错误程序逻辑错误、外部资源问题处理无法处理只能避免必须处理受检或建议处理示例OOM、StackOverflowNPE、IOException1.2 受检异常 vs 非受检异常对比受检异常Checked非受检异常Unchecked编译检查编译器强制要求处理编译器不强制继承Exception非 RuntimeExceptionRuntimeException处理方式try-catch 或 throws可以不处理但建议处理典型场景文件不存在、SQL错误NPE、数组越界代码示例// 受检异常必须处理publicvoidreadFile()throwsIOException{// 方式1throws 声明FileReaderreadernewFileReader(a.txt);}publicvoidreadFile2(){try{// 方式2try-catchFileReaderreadernewFileReader(a.txt);}catch(IOExceptione){e.printStackTrace();}}// 非受检异常可以不处理但不建议publicvoiddivide(inta,intb){intresulta/b;// ArithmeticException编译不报错}二、异常处理机制2.1 五个关键字关键字作用try包裹可能抛出异常的代码catch捕获并处理异常finally无论是否异常都会执行的代码清理资源throw手动抛出异常对象throws声明方法可能抛出的异常2.2 异常捕获规则规则 1先小后大try{// 可能抛出多种异常}catch(FileNotFoundExceptione){// 子类异常先捕获// 处理文件未找到}catch(IOExceptione){// 父类异常后捕获// 处理其他IO异常}catch(Exceptione){// 最后兜底// 处理所有其他异常}⚠️ 如果先捕获父类异常子类异常的 catch 块永远不会执行编译器会报错。规则 2finally 一定会执行try{returntry;// 即使 try 中有 return}finally{System.out.println(finally 也会执行);}唯一例外调用System.exit(0)或 JVM 崩溃。规则 3finally 中的 return 会覆盖 try/catch 的 returnpublicstaticinttest(){try{return1;}finally{return2;// 最终返回 2}}⚠️ 这是常见面试题finally 的 return 会覆盖前面的 return。2.3 try-with-resourcesJava 7传统写法FileReaderreadernull;try{readernewFileReader(a.txt);// 使用 reader}catch(IOExceptione){e.printStackTrace();}finally{if(reader!null){try{reader.close();// 手动关闭资源}catch(IOExceptione){e.printStackTrace();}}}try-with-resourcestry(FileReaderreadernewFileReader(a.txt)){// 使用 reader}catch(IOExceptione){e.printStackTrace();}// 自动关闭不用 finally 只要实现了AutoCloseable接口的类都可以用 try-with-resources。三、自定义异常3.1 为什么需要自定义异常表达业务语义如UserNotFoundException携带业务错误码统一异常处理3.2 如何自定义步骤继承Exception受检异常或RuntimeException非受检异常提供构造方法无参、带 message、带 cause可选添加业务字段如错误码代码示例// 自定义受检异常publicclassBusinessExceptionextendsException{privateintcode;publicBusinessException(){super();}publicBusinessException(Stringmessage){super(message);}publicBusinessException(intcode,Stringmessage){super(message);this.codecode;}publicintgetCode(){returncode;}}// 自定义非受检异常publicclassUserNotFoundExceptionextendsRuntimeException{publicUserNotFoundException(Stringmessage){super(message);}}// 使用publicvoidfindUser(LonguserId){UseruseruserRepository.findById(userId);if(usernull){thrownewUserNotFoundException(用户不存在userId);}}3.3 选择受检还是非受检场景选择调用方必须处理如 IO 操作继承 Exception受检业务逻辑异常如参数校验失败继承 RuntimeException非受检 Spring 框架中大部分业务异常都继承 RuntimeException因为受检异常会导致代码臃肿。四、常见异常类4.1 NullPointerExceptionNPE产生原因调用 null 对象的方法或属性。Stringstrnull;str.length();// NPE常见场景返回值为 null集合元素为 nullSpring 注入失败Autowired 没匹配到拆箱时包装类为 null避免方法// 1. 提前判空if(str!null){str.length();}// 2. 使用 OptionalOptionalStringoptOptional.ofNullable(str);intlenopt.map(String::length).orElse(0);// 3. 使用工具类Objects.requireNonNull(str,str 不能为 null);4.2 ClassCastException产生原因类型转换错误。Objectobjhello;Integernum(Integer)obj;// ClassCastException避免方法if(objinstanceofInteger){Integernum(Integer)obj;}// Java 16 模式匹配if(objinstanceofIntegernum){// 直接使用 num}4.3 IndexOutOfBoundsException产生原因数组或集合索引越界。int[]arrnewint[3];arr[5]10;// ArrayIndexOutOfBoundsExceptionListStringlistnewArrayList();list.get(0);// IndexOutOfBoundsException避免方法if(index0indexarr.length){arr[index]10;}4.4 ConcurrentModificationException产生原因在迭代集合时修改了集合结构。ListStringlistnewArrayList(Arrays.asList(a,b,c));// 错误边遍历边修改for(Strings:list){if(b.equals(s)){list.remove(s);// 抛出 ConcurrentModificationException}}正确方式// 1. 使用 IteratorIteratorStringitlist.iterator();while(it.hasNext()){if(b.equals(it.next())){it.remove();// 使用 Iterator 的 remove}}// 2. 使用 removeIfJava 8list.removeIf(s-b.equals(s));// 3. 使用 CopyOnWriteArrayList并发场景ListStringsafeListnewCopyOnWriteArrayList();4.5 StackOverflowError产生原因栈溢出通常是无限递归。publicvoidrecursive(){recursive();// 无限递归 → StackOverflowError}常见场景递归没有终止条件递归深度过大方法调用链过长五、异常处理最佳实践5.1 不要吞掉异常// 错误吞掉异常try{doSomething();}catch(Exceptione){// 什么都不做异常被吞掉}// 正确至少记录日志try{doSomething();}catch(Exceptione){log.error(执行失败,e);thrownewBusinessException(操作失败,e);}5.2 不要用异常控制流程// 错误用异常控制逻辑try{returnlist.get(index);}catch(IndexOutOfBoundsExceptione){returnnull;}// 正确先判断if(index0indexlist.size()){returnlist.get(index);}returnnull; 异常是异常情况不是正常流程。异常创建和抛出有性能开销。5.3 捕获具体异常而非 Exception// 不推荐捕获所有异常try{// ...}catch(Exceptione){// 不知道具体是什么异常}// 推荐捕获具体异常try{// ...}catch(IOException|SQLExceptione){// 明确知道可能抛出什么异常}5.4 finally 中不要 return// 错误finally 中 returnpublicinttest(){try{return1;}finally{return2;// 会覆盖 try 的 return}}// 正确finally 只做清理publicinttest(){try{return1;}finally{close();// 只做资源清理}}5.5 及时关闭资源// 推荐try-with-resourcestry(ConnectionconndataSource.getConnection()){// 使用连接}catch(SQLExceptione){log.error(数据库错误,e);}六、全局异常处理Spring在 Web 应用中通常使用ControllerAdvice统一处理异常。RestControllerAdvicepublicclassGlobalExceptionHandler{// 处理自定义业务异常ExceptionHandler(BusinessException.class)publicResulthandleBusinessException(BusinessExceptione){log.error(业务异常{},e.getMessage());returnResult.error(e.getCode(),e.getMessage());}// 处理参数校验异常ExceptionHandler(MethodArgumentNotValidException.class)publicResulthandleValidationException(MethodArgumentNotValidExceptione){Stringmessagee.getBindingResult().getFieldError().getDefaultMessage();returnResult.error(400,message);}// 处理所有其他异常ExceptionHandler(Exception.class)publicResulthandleException(Exceptione){log.error(系统异常,e);returnResult.error(500,系统繁忙);}}七、思维导图速览┌───────────────────────────────────────────────────┐ │ Java 异常体系 │ ├───────────────────────────────────────────────────┤ │ │ │ 体系结构 │ │ Throwable │ │ ├── ErrorJVM 错误无法处理 │ │ └── Exception │ │ ├── RuntimeException非受检 │ │ │ ├── NPE / ClassCast / AIOOB │ │ │ └── 业务异常建议继承 │ │ └── 其他受检必须处理 │ │ ├── IOException / SQLException │ │ └── ClassNotFoundException │ │ │ │ 异常处理 │ │ • try-catch-finally │ │ • try-with-resources自动关闭 │ │ • 先小后大子类异常先捕获 │ │ • finally 一定会执行除 System.exit │ │ │ │ 自定义异常 │ │ • 继承 Exception 或 RuntimeException │ │ • 提供构造方法 │ │ • 可携带业务错误码 │ │ │ │ 常见异常 │ │ • NPE判空 / Optional / requireNonNull │ │ • ClassCastExceptioninstanceof 判断 │ │ • ConcurrentModificationException用 Iterator │ │ • StackOverflowError检查递归 │ │ │ │ 最佳实践 │ │ ✗ 不要吞掉异常 │ │ ✗ 不要用异常控制流程 │ │ ✗ finally 不要 return │ │ ✓ 捕获具体异常 │ │ ✓ 及时关闭资源 │ │ ✓ 全局异常处理ControllerAdvice │ └───────────────────────────────────────────────────┘八、写在最后异常体系结构是基础要能画出 Throwable 的完整层次图受检 vs 非受检是高频面试题要能说清楚区别和处理方式常见异常要知道 NPE、ClassCastException、ConcurrentModificationException 的产生原因和避免方法try-with-resources和全局异常处理是实际开发中的最佳实践

相关新闻

探索CountryPicker核心功能:国旗显示、本地化名称与ISO标准支持

探索CountryPicker核心功能:国旗显示、本地化名称与ISO标准支持

探索CountryPicker核心功能:国旗显示、本地化名称与ISO标准支持 【免费下载链接】CountryPicker CountryPicker is a custom UIPickerView subclass that provides an iOS control allowing a user to select a country from a list. It can optionally display a f…

2026/7/12 23:23:07 阅读更多 →
Win32 API 实战:从零构建窗口程序,5步完成消息循环与绘图

Win32 API 实战:从零构建窗口程序,5步完成消息循环与绘图

Win32 API 实战:5步构建完整窗口程序与消息循环1. 环境准备与基础概念Windows图形界面程序开发的核心是Win32 API,这是一组由微软提供的C语言函数库,用于创建窗口、处理消息和绘制界面。与常见的控制台程序不同,Win32程序采用事件…

2026/7/12 23:21:06 阅读更多 →
测试V模型:单元测试-> 集成测试->系统测试->验收测试

测试V模型:单元测试-> 集成测试->系统测试->验收测试

概述 测试的 V 模型 是一种、 /。 软件开发模型,它强调开发和测试活动一一对应、同步进行。 从结构上看,它呈一个 V 字形,左侧是开发阶段(从上到下细化),右侧是测试阶段(从下到上集成),底部是编码与执行。 V 模型将测试活动与开发各阶段明确地对应起来: 需求分析…

2026/7/12 23:19:06 阅读更多 →

最新新闻

医药管理系统

医药管理系统

1 开发技术 1.1 Java 介绍 Java 是由 Sun 公司于 1995 年推出的一种面向对象编程语言,具有跨平台、安全性高、生态成熟等特点。Java 程序运行在 JVM 之上,可实现“一次编写,到处运行”,在企业级 Web 开发中应用广泛,…

2026/7/13 0:21:24 阅读更多 →
宿舍管理系统

宿舍管理系统

1 开发技术 1.1 Java 介绍 Java 是由 Sun 公司于 1995 年推出的一种面向对象编程语言,具有跨平台、安全性高、生态成熟等特点。Java 程序编译后运行于 Java 虚拟机(JVM)之上,遵循“一次编写,到处运行”的设计理念&am…

2026/7/13 0:21:24 阅读更多 →
基于深度学习的停车场管理与车牌识别检测系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

基于深度学习的停车场管理与车牌识别检测系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_

基于深度学习的停车场管理与车牌识别检测系统31(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ 本项目已经训练好模型,配置好环境可直接使用,运行效果见图像如图。该项目有登陆系统和非登陆系统两种,自由可选…

2026/7/13 0:21:24 阅读更多 →
C语言联合体(Union)——让同一块内存“变脸”

C语言联合体(Union)——让同一块内存“变脸”

什么是联合体?联合体是一种特殊的数据类型,它让多个成员共享同一块内存空间。就像一间“变形房间”——你可以把它当作卧室,也可以当作书房,但同一时间只能有一种用途。union Data {int i;float f;char str[20]; };这里 i、f、str…

2026/7/13 0:19:24 阅读更多 →
AutoCAD 2024 3D壳体设计:从草图到STL打印文件的5步完整流程

AutoCAD 2024 3D壳体设计:从草图到STL打印文件的5步完整流程

AutoCAD 2024 3D壳体设计:从草图到STL打印文件的5步完整流程在工业设计和产品开发领域,3D壳体设计一直是工程师和设计师面临的核心挑战之一。无论是电子设备外壳、机械防护罩还是消费品包装,壳体不仅需要满足功能性需求,还要兼顾美…

2026/7/13 0:17:23 阅读更多 →
175.别把急停写在程序末尾!**前置 RETURN 最高优先级安全架构,工业强制标准规范写法**

175.别把急停写在程序末尾!**前置 RETURN 最高优先级安全架构,工业强制标准规范写法**

摘要 可编程逻辑控制器(PLC)是工业自动化领域最核心的控制设备。本文从PLC的硬件架构与扫描周期原理出发,以IEC 61131-3标准的结构化文本(ST)语言为主线,系统讲解PLC编程的核心逻辑。通过一个完整的工业罐装生产线控制案例,提供可直接运行的ST代码,并详细分析运行结果…

2026/7/13 0:13:23 阅读更多 →

日新闻

Palworld存档编辑完全掌握:从零开始实现游戏数据可视化修改

Palworld存档编辑完全掌握:从零开始实现游戏数据可视化修改

Palworld存档编辑完全掌握:从零开始实现游戏数据可视化修改 【免费下载链接】palworld-save-tools Tools for converting Palworld .sav files to JSON and back 项目地址: https://gitcode.com/gh_mirrors/pa/palworld-save-tools 你是否曾经想要调整Palwor…

2026/7/13 0:01:19 阅读更多 →
浦东旧模块回收哪家强?专业评测带你一探究竟

浦东旧模块回收哪家强?专业评测带你一探究竟

于科技迅猛飞速迭代的当下此刻, 旧模块的回收处置, 不但关联着资源的再度利用, 而且更牵扯到数据安全以及环保合规事宜。你是不是也正为那堆积得如同山峦般的旧模块而发愁? 是不是不清楚该怎样安全且高效地去处理它们? 别忧心烦恼, 就在今日, 我会以具备权威影响力的自媒体博…

2026/7/13 0:01:19 阅读更多 →
卡梅德生物技术快报|重组蛋白的表达和纯化:IMAC 金属螯合色谱全流程工艺手册|基质 - 配基 - 金属离子匹配与蛋白质分离纯化参数优化

卡梅德生物技术快报|重组蛋白的表达和纯化:IMAC 金属螯合色谱全流程工艺手册|基质 - 配基 - 金属离子匹配与蛋白质分离纯化参数优化

1 研究背景与现存技术痛点(提出问题)基因工程、蛋白质组学、生物制药研发流程中,蛋白质分离纯化是决定下游实验成败的关键环节。当前实验室常规蛋白质分离纯化工艺存在三类难以标准化的技术瓶颈:传统离子交换、分子筛层析无特异性…

2026/7/13 0:05:20 阅读更多 →

周新闻

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨

互联网大厂 Java 求职面试:燕双非的搞笑回答与技术探讨 在一个阳光明媚的上午,互联网大厂的面试官坐在桌前,准备迎接他的面试候选人——燕双非,一个以搞笑和幽默著称的程序员。第一轮提问 面试官:燕双非,作…

2026/7/12 0:03:13 阅读更多 →
车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估

车载以太网PMA测试设备选型:示波器、VNA、信号源3类仪器关键参数与预算评估在智能驾驶和车联网技术快速发展的今天,车载以太网作为新一代车载网络的核心传输技术,其物理层性能直接决定了数据传输的可靠性和稳定性。1000BASE-T1作为当前主流的…

2026/7/12 0:03:14 阅读更多 →
VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战,5步完成Keil工程转换

VSCode EIDE 插件 2.0:APM32/STM32 项目迁移实战指南嵌入式开发领域正经历一场工具链的静默革命。当传统Keil用户首次打开VSCode的扩展市场搜索EIDE时,往往会惊讶于这个看似简单的插件竟能重构十余年的开发习惯。本文将揭示如何用五个精准步骤&#xff0…

2026/7/12 0:03:14 阅读更多 →

月新闻