Exception异常机制详细讲解

目录

  • 一、异常
    • 1.1 什么是异常
    • 1.2 异常机制的作用
    • 1.3 常见的异常
    • 2.3 异常的分类
      • 1. Error
      • 2. Exception
      • ① 运行时异常
      • ② 编译期异常
      • 总结:
  • 二、异常的处理
    • 2.1 抛出异常
    • 3.1 抛出异常语法
    • 3.2 试图捕获异常
    • 3.3 捕获异常与抛出异常的区别
      • 1. 抛出异常
      • 2.捕获异常
  • 三、finally
  • 四、throw 异常的产生(创建)
  • 四、异常类的API
  • 五、自定义异常
    • 最后

一、异常

1.1 什么是异常

  • 异常(exception),就是程序中出现的错误
  • 就好比你在工作的时候,突然家里出了点情况,中断了你工作,这就是出现了异常情况。

1.2 异常机制的作用

  • 通过打印出的异常信息,我们可以知道是哪里的代码出现了问题,并大概了解为什么会出现这个问题,方便我们去解决问题

1.3 常见的异常

  • 算术异常 ArithmeticException

  • 数组下标越界异常 ArrayIndexOutOfBoundsException

  • 空指针异常 NullPointerException

  • 类转换异常ClassCastException

  • 解析异常 ParseException

  • 堆栈内存溢出错误 StackOverflowError

2.3 异常的分类

  • 异常也是一种类,Throwable 类是 Java 语言中所有错误或异常的超类。

1. Error

  • Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。
  • 也就是Error一般都是严重问题,遇到必须里面立马解决,所以不应该捕获…
  • 例如:堆栈内存溢出错误 StackOverflowError

2. Exception

可以抛出,也可以捕获的异常

Exception子类:RuntimeException(运行时异常)和其他异常类

① 运行时异常

  • 这些异常在编译时不强制要求处理,通常是由程序中的错误引起的,例如 NullPointerException、ArrayIndexOutOfBoundsException 等,这类异常可以选择处理,但并非强制要求。

在这里插入图片描述

  • 这些类是: RuntimeException及其子类的都是运行时异常

在这里插入图片描述

② 编译期异常

  • 编译期异常是用户错误或问题引起的异常,这些异常在编译时强制要求程序员处理。例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。

在这里插入图片描述

总结:

Throwable
Error
Exception
验证问题,不能捕获,只能抛出
运行时异常
编译期异常
是RuntimeException的子类
默认不用处理
除了RuntimeException的子类的都是
必须强制处理

二、异常的处理

我们知道异常的基本概念了,那异常如何处理呢?

  • 异常的处理只有两种方式

    • 抛出异常
    • 捕获异常

2.1 抛出异常

  • 什么是抛出异常?

    目前为止任何异常,默认的处理方式都是抛出

    所谓抛出异常就是直接将错误信息打印到控制台
    在这里插入图片描述

3.1 抛出异常语法

  • 前面讲到运行时异常,可以不用处理,通过上图也发现系统会默认自动抛出
  • 如果是编译期异常,想要抛出异常,语法是
    • 位置: 在方法参数列表后,{}前
    • 写:throws 异常类名,类名2,…
    public static void main(String[] args) throws ArithmeticException,ArrayIndexOutOfBoundsException {}
  • 声明抛出异常后,什么效果?
  • 如果代码一切正常,虽然声明的有抛出异常,也不会在控制台打印异常信息
  • 如果代码真的有异常,声明了抛出异常,
    • 1错误信息就会在控制台打印
    • 2抛出异常后,后续代码不再执行
    // 以下代码中19行报错,4,5,6,7.7都不再执行public static void main(String[] args) {System.out.println(0.0 );m1();System.out.println(7.7 );}public static void m1() {System.out.println(1);System.out.println(2);m2();System.out.println(5);System.out.println(6);}public static void m2(){System.out.println(3);System.out.println(4 / 0);System.out.println(4 );}
  • 但是如果方法抛出的是编译期异常,谁调用这个抛出编译期异常的方法,那么哪个方法就得处理!!

在这里插入图片描述

  • 特殊的 ,关于抛出异常在重写方法时也有要求…
  • 子类的重写后,方法抛出的异常范围要 <= 父类的异常范围
  • 特殊的,如果父类方法没有抛出异常,那么子类方法内有异常也不能抛出,只能捕获

总结抛出异常

  • 哪里抛出的?
    • 方法签名上只是声明可能抛出的异常类型
    • 方法体内,执行到某一行代码,如果有错才会抛出
  • 抛给谁?
    • 如果有异常抛出,谁调用抛给哪个方法
    • 最终抛出到main
    • main方法抛出到jvm,jvm打印到控制台
  • 抛到哪?
    • 抛出到控制台
  • 抛出了啥?
    • 异常的线程信息
    • 异常类型
    • 异常原因
    • 异常位置

3.2 试图捕获异常

试图捕获(try-catch)

  • 语法
try{// 可能会有报错的代码
} catch (异常类名 对象名){// 如果抓到异常,执行这里
}

执行流程:

  • 代码正常运行,执行try后
  • 进入try执行,如果try内一切正常,catch就跳过不执行
  • 如果try内有异常
    • try内异常处后续不执行
    • catch捕获到异常后,就会执行
  • 无论try内有无异常,try-catch后的代码都能运行
    public static void main(String[] args) {System.out.println(1);System.out.println(2);try {System.out.println(3);System.out.println(4.1);System.out.println(4/0);System.out.println(4.2);}catch (ArithmeticException ae){System.out.println("捕获到了异常:"+ae );}System.out.println(5);}
  • 特殊情况1: 出现的异常和捕获的异常不一致,try-catch失效

在这里插入图片描述

  • 特殊情况2: 允许同时声明catch多个异常

在这里插入图片描述

  • 特殊情况3: 如果真需要catch写多个异常,用于去捕获多种异常的话,建议这么写,写一个Exception,直接捕获最大类异常,这样所有异常子类都可以捕获

image-20240603114043937

3.3 捕获异常与抛出异常的区别

1. 抛出异常

在这里插入图片描述

通过上图发现程序中断,后续代码无法执行

2.捕获异常

在这里插入图片描述

通过上图发现,当try代码块中出现异常后,catch代码块捕获到异常,执行catch中的语句,而且try-catch外面的语句正常执行

三、finally

  • finally配合try-catch使用
  • 作用: 最终一定会执行,即放在finally里面的代码,之前无论有无报错,无论是抛出还是捕获,fianlly里面的代码最终一定能执行

语法:

try{// ...
}catch(Exception e){}finally{}

或者

try{// ...   
}finally{}

finally一般用在 关闭流/通道的场景中,用于及时释放资源

例如: IO流,jdbc连接

四、throw 异常的产生(创建)

  • 之前说的是抛出异常,捕获异常都是异常出现了之后的解决方案.

如何制造产生异常呢?

产生异常,两个步骤:

  • 创建异常对象
  • 通过throw 抛出异常对象
    • 需要注意,throw抛出的是编译期异常,需要强制处理
    • throw抛出的是运行时异常,可以默认不用处理

public class Demo5 {public static void main(String[] args) throws ParseException {String s = parseBirthday2("41011120240101123");System.out.println(s );}/**需求: 解析身份证号中的生日,要求身份证号长度18位,否则抛出异常*/public static String parseBirthday(String idNumber) throws ParseException{if (idNumber.length() == 18) {return idNumber.substring(6,14);}// 抛出异常(编译期异常,需要处理)throw new ParseException("生日解析出错,格式不正确",1);}public static String parseBirthday2(String idNumber) {if (idNumber.length() == 18) {return idNumber.substring(6,14);}// 抛出异常(运行时异常,不用管)throw new RuntimeException("2222生日解析出错,格式不正确");}
}
  • 总结throw和throws…
throwthrows
位置方法体内方法签名上
后面写什么跟1个异常对象跟异常类名,且允许多个
作用一定会抛出异常的声明抛出的异常类型,但是不一定有异常

四、异常类的API

查阅API,发现所有异常,方法基本上都直接继承自Throwable类,常用的方法

  • 构造方法 Throwable(String message)
    • 所有的异常对象,都通过有参构造将异常信息传递给Throwable父类
    • 且这个message就是异常信息
  • String getMessage()
  • void printStackTrace()
  • String toString()
public class Demo6 {public static void main(String[] args) {try {System.out.println(1/0 );}catch (ArithmeticException ae) {// String message = ae.getMessage( );// System.out.println("message = " + message);//// String string = ae.toString( );// System.out.println("string = " + string);// 获得这些异常信息,将来将其输出到本地磁盘日志文件ae.printStackTrace();}}
}

五、自定义异常

自定义异常实现步骤

  1. 创建一个异常类,命名规范XxxxException
  2. 继承一个合适的父类
    1. 继承编译期异常
    2. 继承运行时异常
  3. 设计一个有参构造,将异常信息参数通过super传递给父类异常

如何使用自定义异常类:

  • 在需要使用的方法内部,通过throw+该异常对象,将其抛出

// 异常类

public class AgeOutOfBoundsException extends Exception{public AgeOutOfBoundsException(String msg){super(msg);}}

// 使用异常

public class Dog {private int age;public int getAge() {return age;}public void setAge(int age) throws Exception{if (age <= 0 || age >= 100) {throw  new AgeOutOfBoundsException("年龄"+age+"越界!");}this.age = age;}
}

最后

如果感觉有收获的话,点个赞 👍🏻 吧。
❤️❤️❤️本人菜鸟修行期,如有错误,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/22216.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud:构建高可用分布式系统的利器

摘要&#xff1a;本文将介绍Spring Cloud&#xff0c;一个基于Spring Boot的开源微服务架构工具集。我们将探讨Spring Cloud的核心组件、特性以及如何使用Spring Cloud构建高可用、分布式系统。通过本文&#xff0c;读者将了解到Spring Cloud在实现微服务架构中的应用和优势。 …

【Springcloud微服务】MybatisPlus下篇

&#x1f525; 本文由 程序喵正在路上 原创&#xff0c;CSDN首发&#xff01; &#x1f496; 系列专栏&#xff1a;Springcloud微服务 &#x1f320; 首发时间&#xff1a;2024年6月4日 &#x1f98b; 欢迎关注&#x1f5b1;点赞&#x1f44d;收藏&#x1f31f;留言&#x1f43…

24、matlab二维和三维网格(meshgrid函数)以及散点数据插值 griddata()函数

1、二维和三维网格(meshgrid函数) 语法 语法1:[X,Y] = meshgrid(x,y) 基于向量 x 和 y 中包含的坐标返回二维网格坐标。 语法2:[X,Y] = meshgrid(x) 与 [X,Y] = meshgrid(x,x) 相同,并返回网格大小为 length(x)length(x) 的方形网格坐标。 语法3:[X,Y,Z] = meshgrid(x,y,…

弘君资本炒股开户:如何看待股价波动?

在股票商场上股价的动摇无疑是投资者最为关心的话题之一&#xff0c;面临股价的起伏不定投资者往往会感到迷茫和焦虑。关于怎么看待股价动摇&#xff0c;弘君资本下面就为大家详细介绍一下。 股价动摇是股市运行的常态&#xff0c;股市是国民经济的晴雨表&#xff0c;股票价格…

SpringBoot+layui实现Excel导入操作

excel导入步骤 第三方插件引入插件 效果图 &#xff08;方法1&#xff09;代码实现&#xff08;方法1&#xff09;Html代码&#xff08; 公共&#xff09;下载导入模板 js实现 &#xff08;方法1&#xff09;上传文件实现 效果图&#xff08;方法2&#xff09;代码实现&#xf…

多语言大模型 Aya-23 开源!覆盖23种语言,性能刷新SOTA

文章目录 1. Aya-23 技术特点1.1 预训练阶段1.2 指令微调阶段 2. Aya-23 性能表现3. Aya-23 多语言任务评估4. Aya-23 支持 23 种语言5. Aya-23 应用场景 近年来&#xff0c;多语言大模型&#xff08;MLLM&#xff09;发展迅速&#xff0c;但大多数模型的性能依然存在显著差距&…

“滴滴打车,用友入账”,YonSuite商旅费控助力企业“降低成本”更进一步

在当今竞争激烈的商业环境中&#xff0c;企业对于成本控制和效率提升的需求日益迫切。特别是在商旅管理方面&#xff0c;如何有效整合资源、优化流程、降低费用&#xff0c;成为了成长型企业关注的焦点。用友YonSuite商旅费控作为用友集团旗下的重要产品&#xff0c;凭借其卓越…

ctfshow pwn17-18

毛坯的人生和精装的朋友圈 pwn17 while ( 1 ){menu();v4 0;puts("\nEnter the command you want choose:(1.2.3.4 or 5)\n");__isoc99_scanf("%d", &v4);switch ( v4 ){case 1:system("id");break;case 2:puts("Which directory?(/,…

卡尔曼滤波算法的matlab实现

卡尔曼滤波算法的matlab实现 figure; hold on;Z(1:1:100); %观测值&#xff1a;第一秒观测1m 第二秒观测两米 匀速运动, 每秒1m, 最后拟合的也是速度 1m/splot(Z); plot([0,100], [1,1]);noiserandn(1,100)*0.5; %生成方差为1的高斯噪声 ZZnoise; % 加入噪声plot(Z);X[0;…

LabVIEW动态力传感器校准系统

LabVIEW动态力传感器校准系统 开发了一种基于LabVIEW的动态力传感器校准系统。系统主要用于动态力的测量和校准&#xff0c;通过高度集成化和自动化的设计&#xff0c;显著提升校准的效率和精确度。系统采用冲击法进行动态校准&#xff0c;涵盖了完整的硬件设计和软件开发流程…

智能体应用开发:构建各类垂直领域的ai智能体应用

最近在做个类似的项目&#xff0c;有用到这方面的知识&#xff0c;顺便做一些记录和笔记吧&#xff0c;希望能帮到大家了解智能体应用开发 目录 引言 AI原生应用的兴起 智能体在AI中的角色 实现原理详解 机器学习基础 数据管理与关联数据库 数据结构 Embedding 检索方…

卫星位置解算

前言&#xff1a; 本章节代码均在Gitee中开源&#xff1a; 卫星位置计算代码https://gitee.com/Ehundred/navigation-engineering/tree/master/%E5%8D%AB%E6%98%9F%E5%AF%BC%E8%88%AA%E5%8E%9F%E7%90%86/GPS%E5%8D%AB%E6%98%9F%E4%BD%8D%E7%BD%AE%E8%A7%A3%E7%AE%97/Satellit…

心怀希望の光栅化

还记得什么是光栅化咩&#xff1f; 将三维空间的几何形体显现在屏幕上&#xff0c;这就是光栅化&#xff08;游戏、实时图形学的应用&#xff09; Perspective Projection 在正交投影里如何定义三维空间中的立方体呢&#xff1f; 用x轴的覆盖&#xff08;左、右&#xff09;…

【UML用户指南】-02-UML基本元素的介绍(二)

目录 1、语法和语义规则 2、UML中的公共机制 &#xff08;1&#xff09;规约 &#xff08;2&#xff09;修饰 &#xff08;3&#xff09;通用划分 &#xff08;4&#xff09;扩展机制 衍型/版型/类型&#xff08;stereotype&#xff09; 标记值 &#xff08;tagged val…

Java编程常见问题汇总四

系列文章目录 文章目录 系列文章目录前言一、忽略所有异常二、重复包装RuntimeException三、不正确的传播异常四、用日志记录异常五、异常处理不彻底 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。…

[C/C++]_[初级]_[在Windows和macOS平台上导出动态库的一些思考]

场景 最近看了《COM本质论》里关于如何设计基于抽象基类作为二进制接口,把编译器和链接器的实现隐藏在这个二进制接口中,从而使用该DLL时不需要重新编译。在编译出C接口时,发现接口名直接是函数名,比如BindNativePort,怎么不是_BindNativePort?说明 VC++导出的函数默认是使…

Google Earth Engine精度评价方法

今天讲讲如何在GEE中做最后的精度评价。主要是因为在和许多读者或通过交流群&#xff0c;或通过私聊沟通过程中&#xff0c;发现很多人还不是很理解在GEE中分类后精度评价的问题。 在进行评价之前&#xff0c;需要明晰在GEE中精度评价分为哪几种情况。我们这里说的是两种情况。…

收藏品NFT的开发流程

开发收藏品NFT的流程涉及多个阶段&#xff0c;从概念化和设计到技术实现和市场推广。以下是详细的开发步骤&#xff0c;通过这些步骤&#xff0c;可以成功开发和发布收藏品NFT项目&#xff0c;吸引用户和投资者&#xff0c;并确保项目的持续运营和成功。北京木奇移动技术有限公…

Fiddler入门(接口抓包及APP测试)

目录 一、Fiddler基础介绍 二、Fiddler的作用 三、Fiddler安装 四、Fiddler界面功能介绍 1、界面介绍 1&#xff09;、菜单栏介绍 2&#xff09;、工具栏介绍 3&#xff09;、会话栏介绍 五、Fiddler抓取https数据 &#xff08;面试题&#xff09; 六、Fiddler…

【刷题(17)】技巧

一 技巧基础 二 136. 只出现一次的数字 1 题目 2 解题思路 哈希表map 其实看到题目数组中某个元素出现的次数也可以直接用unordered_map容器统计每一个元素出现的次数&#xff0c;然后在遍历整个map容器查看是否有元素出现的次数等于1 3 code class Solution { public:in…