【JavaSE】基础笔记 - 异常(Exception)
目录
1、异常的概念和体系结构
1.1、异常的概念
1.2、 异常的体系结构
1.3 异常的分类
2、异常的处理
2.1、防御式编程
2.2、异常的抛出
2.3、异常的捕获
2.3.1、异常声明throws
2.3.2、try-catch捕获并处理
3、自定义异常类

1、异常的概念和体系结构
1.1、异常的概念
在日常开发中,绞尽脑汁将代码写的尽善尽美,在程序运行过程中,难免会出现一些奇奇怪怪的问题。有时通过代码很难去控制,比如:数据格式不对、网络不通畅、内存报警等。
当出现这些问题时,JVM虚拟机会自动捕获这些问题并抛出错误信息。在Java中,将程序执行过程中发生的不正常行为称为异常。
例如:
(1)算术异常
System.out.println(10 / 0);

(2)数组越界异常
int[] arr = {1, 2, 3};
System.out.println(arr[100]);

(3)空指针异常
int[] arr = null;
System.out.println(arr.length);

从上述过程中可以看到,java中不同类型的异常,都有与其对应的类来进行描述。
1.2、 异常的体系结构
异常种类繁多,为了对不同异常或者错误进行很好的分类管理,Java内部维护了一个异常的体系结构:

从上图中可以看到:
- Throwable:是异常体系的顶层类,其派生出两个重要的子类, Error 和 Exception
- Error:指的是Java虚拟机无法解决的严重问题,比如:JVM的内部错误、资源耗尽等,典型代表:StackOverflowError和OutOfMemoryError,一旦发生回力乏术。
- Exception:异常产生后程序员可以通过代码进行处理,使程序继续执行。比如:感冒、发烧。我们平时所说的异常就是Exception。
1.3 异常的分类
异常可能在编译时发生,也可能在程序运行时发生,根据发生的时机不同,可以将异常分为:
1. 编译时异常
在程序编译期间发生的异常,称为编译时异常,也称为受检查异常(Checked Exception)
2. 运行时异常
在程序执行期间发生的异常,称为运行时异常,也称为非受检查异常(Unchecked Exception)
RunTimeException以及其子类对应的异常,都称为运行时异常。比如:NullPointerException、ArrayIndexOutOfBoundsException、ArithmeticException。
注意:编译时出现的语法性错误,不能称之为异常。例如将 System.out.println 拼写错了, 写成了system.out.println. 此时编译过程中就会出错, 这是 "编译期" 出错。而运行时指的是程序已经编译通过得到class 文件了, 再由 JVM 执行过程中出现的错误。
2、异常的处理
2.1、防御式编程
错误在代码中是客观存在的. 因此我们要让程序出现问题的时候及时通知程序猿。主要的方式
1. LBYL: Look Before You Leap. 在操作之前就做充分的检查。即:事前防御型
boolean ret = false;ret = 登陆游戏();if (!ret) {处理登陆游戏错误;return;}ret = 开始匹配();if (!ret) {处理匹配错误;return;}ret = 游戏确认();if (!ret) {处理游戏确认错误;return;}ret = 选择英雄();if (!ret) {处理选择英雄错误;return;}ret = 载入游戏画面();if (!ret) {处理载入游戏错误;return;}
缺陷:正常流程和错误处理流程代码混在一起, 代码整体显的比较混乱。
2. EAFP: It's Easier to Ask Forgiveness than Permission. "事后获取原谅比事前获取许可更容易". 也就是先操作, 遇到问题再处理. 即:事后认错型
try {登陆游戏();开始匹配();游戏确认();选择英雄();载入游戏画面();
...} catch (登陆游戏异常) {处理登陆游戏异常;} catch (开始匹配异常) {处理开始匹配异常;} catch (游戏确认异常) {处理游戏确认异常;} catch (选择英雄异常) {处理选择英雄异常;} catch (载入游戏画面异常) {处理载入游戏画面异常;}
优势:正常流程和错误流程是分离开的, 程序员更关注正常流程,代码更清晰,容易理解代码
2.2、异常的抛出
在编写程序时,如果程序中出现错误,此时就需要将错误的信息告知给调用者,比如:参数检测。
在Java中,可以借助throw关键字,抛出一个指定的异常对象,将错误信息告知给调用者。具体语法如下:
throw new XXXException("异常产生的原因");
【注意事项】
- throw必须写在方法体内部
- 抛出的对象必须是Exception 或者 Exception 的子类对象
- 如果抛出的是 RunTimeException 或者 RunTimeException 的子类,则可以不用处理,直接交给JVM来处理
- 如果抛出的是编译时异常,用户必须处理,否则无法通过编译
- 异常一旦抛出,其后的代码就不会执行(除非使用try-catch捕捉可能异常代码)
2.3、异常的捕获
异常的捕获,也就是异常的具体处理方式。
主要有两种:异常声明throws 以及 try-catch捕获处理。
2.3.1、异常声明throws
处在方法声明时参数列表之后,当方法中抛出编译时异常,用户不想处理该异常,此时就可以借助throws将异常抛给方法的调用者来处理。即当前方法不处理异常,提醒方法的调用者处理异常。
语法格式:
修饰符 返回值类型 方法名(参数列表) throws 异常类型1,异常类型2...{}
【注意事项】
- throws必须跟在方法的参数列表之后。
- 声明的异常必须是 Exception 或者 Exception 的子类。
- 方法内部如果抛出了多个异常,throws之后必须跟多个异常类型,之间用逗号隔开,如果抛出多个异常类型具有父子关系,直接声明父类即可。
- 调用声明抛出异常的方法时,调用者必须对该异常进行处理,或者继续使用throws抛出。
2.3.2、try-catch捕获并处理
throws对异常并没有真正处理,而是将异常报告给抛出异常方法的调用者,由调用者处理。如果真正要对异常进行处理,就需要try-catch。
语法格式:
public static void main(String[] args) {try {// 将可能出现异常的代码放在这里} catch (要捕获的异常类型 e) {// 如果try中的代码抛出异常了,此处catch捕获时异常类型与try中抛出的异常类型一致时,或者是try中抛出异常的基类时,就会被捕获到// 对异常就可以正常处理,处理完成后,跳出try-catch结构,继续执行后序代码} finally {// 此处代码一定会被执行到}// 后序代码// 当异常被捕获到时,异常就被处理了,这里的后序代码一定会执行// 如果捕获了,由于捕获时类型不对,那就没有捕获到,这里的代码就不会被执行}
finally是什么?
finally中代码是一定会被执行的。
在写程序时,有些特定的代码,不论程序是否发生异常,都需要执行,比如程序中打开的资源:网络连接、数据库连接、IO流等,在程序正常或者异常退出时,必须要对资源进进行回收。另外,因为异常会引发程序的跳转,可能导致有些语句执行不到,finally就是用来解决这个问题的。
注意:不是说放在try中的代码就一定会抛出异常,只是在try内写的代码在抛出异常时会被捕捉到。需要理解一个误区。
关于异常的处理方式
异常的种类有很多, 我们要根据不同的业务场景来决定.
对于比较严重的问题(例如和算钱相关的场景), 应该让程序直接崩溃, 防止造成更严重的后果
对于不太严重的问题(大多数场景), 可以记录错误日志, 并通过监控报警程序及时通知程序猿
对于可能会恢复的问题(和网络相关的场景), 可以尝试进行重试。
我们记录的错误日志是出现异常的方法调用信息, 能很快速的让我们找到出现异常的位置. 以后在实际工作中我们会采取更完备的方式来记录异常信息。
【异常处理的流程总结】
- 程序先执行 try 中的代码。
- 如果 try 中的代码出现异常, 就会结束 try 中的代码, 看和 catch 中的异常类型是否匹配。
- 如果找到匹配的异常类型, 就会执行 catch 中的代码。
- 如果没有找到匹配的异常类型, 就会将异常向上传递到上层调用者。
- 无论是否找到匹配的异常类型, finally 中的代码都会被执行到(在该方法结束之前执行)。
- 如果上层调用者也没有处理的了异常, 就继续向上传递。
- 一直到 main 方法也没有合适的代码处理异常, 就会交给 JVM 来进行处理, 此时程序就会异常终止。
3、自定义异常类
自定义异常类必须继承自Exception或者RunTimeException,并且实现一个带有String类型参数的构造方法,参数含义:出现异常的原因
例如, 我们实现一个用户登陆功能。
//用于判断用户名的异常类
public class UserNameException extends RuntimeException{public UserNameException() {super();}public UserNameException(String s) {super(s);}
}
//用于判断密码的异常类
public class UserPasswordException extends RuntimeException {public UserPasswordException() {super();}public UserPasswordException(String s) {super(s);}
}
用户进行登录,用户名或者密码错误时需要提示用户名或密码错误,但是如果直接使用println打印,那么只能知道错了,但是无法得知是错在哪一行,而使用自定义异常类就能解决这个问题,方便程序员在大型工程中快速找到报错地方。
class Login {public String userName = "admin";public String passWord = "123456";public void login(String userName, String passWord) {if(!this.userName.equals(userName)) {//System.out.println("用户名错误!");//使用自定义异常类来提示用户名错误throw new UserNameException("用户名错误!");}if(!this.passWord.equals(passWord)) {//System.out.println("密码错误!");//使用自定义异常类来提示密码错误throw new UserPasswordException("密码错误!");}}
}public class Main {public static void main(String[] args) {try {Login l = new Login();l.login("admin", "123");} catch (UserNameException | UserPasswordException e) {e.printStackTrace();}}
}
【运行结果】

【注意事项】
- 自定义异常通常会继承自 Exception 或者 RuntimeException。
- 继承自 Exception 的异常默认是受查异常。
- 继承自 RuntimeException 的异常默认是非受查异常。
博主推荐:
【计算机组成原理】知识点巩固 - 存储器概述-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/134482974?spm=1001.2014.3001.5502
【JavaSE】基础笔记 - 图书管理系统(保姆教程,含源码)-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/134467911?spm=1001.2014.3001.5502
【JavaSE】基础笔记 - 类和对象(下)-CSDN博客
https://blog.csdn.net/zzzzzhxxx/article/details/134248822?spm=1001.2014.3001.5502
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!
相关文章:
【JavaSE】基础笔记 - 异常(Exception)
目录 1、异常的概念和体系结构 1.1、异常的概念 1.2、 异常的体系结构 1.3 异常的分类 2、异常的处理 2.1、防御式编程 2.2、异常的抛出 2.3、异常的捕获 2.3.1、异常声明throws 2.3.2、try-catch捕获并处理 3、自定义异常类 1、异常的概念和体系结构 1.1、异常的…...
QTableWidget——编辑单元格
文章目录 前言熟悉QTableWiget,通过实现单元格的合并、拆分、通过编辑界面实现表格内容及属性的配置、实现表格的粘贴复制功能熟悉QTableWiget的属性 一、[单元格的合并、拆分](https://blog.csdn.net/qq_15672897/article/details/134476530?spm1001.2014.3001.55…...
编译QT Mysql库并集成使用
安装MSVC编译器与Windows 10 SDK 打开Visual Studio Installer,如果已经安装过内容了可能是如下页面,点击修改(头一回打开的话不需要这一步): 然后在工作负荷中勾选使用C的桌面开发,它会帮我们勾选好一些…...
利用企业被执行人信息查询API保障商业交易安全
前言 在当今竞争激烈的商业环境中,企业为了保障商业交易的安全性不断寻求新的手段。随着技术的发展,利用企业被执行人信息查询API已经成为了一种强有力的工具,能够帮助企业在商业交易中降低风险,提高合作的信任度。 企业被执行人…...
【深度学习】P1 深度学习基础框架 - 张量 Tensor
深度学习基础框架 张量 Tensor 张量数据操作导入创建张量获取张量信息改变张量张量运算 张量与内存 张量 Pytorch 是一个深度学习框架,用于开发和训练神经网络模型。 而其核心数据结构,则是张量 Tensor,类似于 Numpy 数组,但是可…...
vue2 识别页面参数中的html
在Vue 2中,你可以使用v-html指令来识别页面参数中的HTML内容。v-html指令允许你将HTML代码作为Vue模板的一部分进行渲染。 以下是一个示例,演示了如何在Vue 2中使用v-html指令来识别页面参数中的HTML内容: <template><div v-html&…...
matlab 一些画图法总结(持续更新)
*****************************************画Dmd_L极坐标表示法**************************************** if(~exist(Dmd_L_array)) Dmd_L_array []; end Dmd_L_array [Dmd_L_array; Dmd_L]; thetaangle(Dmd_L_array); rabs(Dmd_L_array); polarplot(theta,r,o); *****…...
MDK AC5和AC6是什么?在KEIL5中添加和选择ARMCC版本
前言 看视频有UP主提到“AC5”“AC6”这样的词,一开始有些不理解,原来他说的是ARMCC版本。 keil自带的是ARMCC5,由于ARMCC5已经停止维护了,很多开发者会选择ARMCC6。 在维护公司“成年往事”项目可能就会遇到新KEIL旧版本编译器…...
杰发科技AC7801——EEP内存分布情况
简介 按照文档进行配置 核心代码如下 /*!* file sweeprom_demo.c** brief This file provides sweeprom demo test function.**//* Includes */ #include <stdlib.h> #include "ac780x_sweeprom.h" #include "ac780x_debugout.h"/* Define …...
【mybatis注解实现条件查询】
文章目录 步骤1: 引入MyBatis依赖步骤2: 创建数据模型步骤3: 创建Mapper接口步骤4: 配置MyBatis步骤5: 执行条件查询 步骤1: 引入MyBatis依赖 <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.x.…...
【广州华锐互动】VR线上课件制作软件满足数字化教学需求
随着科技的不断发展,虚拟现实(VR)技术在教学领域的应用逐渐成为趋势。其中,广州华锐互动开发的VR线上课件制作软件更是备受关注。这种工具为教师提供了便捷的制作VR课件的手段,使得VR教学成为可能,极大地丰…...
MySQL 中 DELETE 语句中可以使用别名么?
某天,正按照业务的要求删除不需要的数据,在执行 DELETE 语句时,竟然出现了报错! 作者:林靖华,开源数据库技术爱好者,擅长MySQL和Redis的运维 爱可生开源社区出品,原创内容未经授权不…...
flutter创建不同样式的按钮,背景色,边框,圆角,圆形,大小都可以设置
在ui设计中,可能按钮会有不同的样式需要你来写出来,所以按钮的不同样式,应该是最基础的功能,在这里我们赶紧学起来吧,web端可能展示有问题,需要优化,但是基本样式还是出来了 我是将所有的按钮放…...
【C++】标准模板库STL作业(其二)
🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:…...
基于SpringBoot+Redis实现点赞/排行榜功能,可同理实现收藏/关注功能,可拓展实现共同好友/共同关注/关注推送功能
前言 简单记录一下在SpringBoot项目中,使用Redis实现点赞/排行榜功能,可同理实现收藏/关注功能,可拓展实现共同好友/共同关注/关注推送功。主要用到了Redis中的Set集合和ZSet集合。 一、指定使用某个索引的数据库 在Redis中,可…...
AI“胡说八道”?怎么解?
原创 | 文 BFT机器人 01 引言 近年来,人工智能产业迅猛发展,大型语言模型GPT-4发展势头强劲,OpenAI推出ChatGPT、微软推出Bing、马斯克推出“最好的聊天机器人Grok”……科技巨头纷纷入局AI领域,引入人工智能作为办公工具的行业…...
[SIGGRAPH-23] 3D Gaussian Splatting for Real-Time Radiance Field Rendering
pdf | proj | code 本文提出一种新的3D数据表达形式3D Gaussians。每个Gaussian由以下参数组成:中心点位置、协方差矩阵、可见性、颜色。通过世界坐标系到相机坐标系,再到图像坐标系的仿射关系,可将3D Gaussian映射到相机坐标系,通…...
大话设计模式C++实现
大话设计模式,讲得非常好,但是作者是用C#写的,为了方便C程序员,使用C写了大话设计模式的代码 详情见Github:https://github.com/liubamboo/BigTalkDesignPattern...
IT 领域中的主要自动化趋势
48%的IT自动化流程属于IT服务管理,过去一年中,IT运维自动化增长了272%。 IT部门从交付者转变为战略伙伴 今年的《工作自动化指数》数据显示,自动化正在蔓延到组织的各个部门,越来越多的部门采用自动化,并且IT以外的员工…...
使用Python解析CAN总线
缘起 在新能源车辆的开发和维护中,经常需要对CAN总线数据进行分析。CANOE等总线软件虽然方便,但功能有限,难以满足数据分析的要求。Matlab的Vehicle Network Toolbox可以方便的进行数据解析和分析,它是闭源且收费的。因此&#x…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
PostgreSQL——环境搭建
一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在࿰…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
[拓扑优化] 1.概述
常见的拓扑优化方法有:均匀化法、变密度法、渐进结构优化法、水平集法、移动可变形组件法等。 常见的数值计算方法有:有限元法、有限差分法、边界元法、离散元法、无网格法、扩展有限元法、等几何分析等。 将上述数值计算方法与拓扑优化方法结合&#…...
