【Java学习笔记】异常处理

生活中我们在使用一些产品的时候,经常会碰到一些异常情况。例如,使用ATM机取钱的时,机器会突然出现故障导致无法完成正常的取钱业务,甚至吞卡;在乘坐地铁时,地铁出现异常无法按时启动和运行;使用手机时,手机突然自动关机,等等。这些产品的异常情况,有些是系统硬件的问题,但更多的情况是软件出现了问题。
使用Java开发软件时,无论程序员多么小心谨慎,产品反复测试,还是会出现程序错误的现象。所以,优秀的编程语言可以为程序员提供高效、可靠的错误处理机制,便于开发高质量的软件产品。
Java语言提供了一种面向对象异常处理机制来报告和处理错误,这种异常处理机制对异常的处理都封装在异常类中完成。程序在运行过程中,如果出现异常,则会抛出一个异常类对象。

1.异常的概念

  • 在程序的设计过程中通常会遇到两种不可避免的错误:编译错误和运行错误。
  • 编译错误是由于编写的程序不符合程序的语法规定而导致的语法问题。大部分的编译错误,是由于对编程语言的语法不熟悉或拼写错误引起的。如果违反了编程语言规则,就会导致程序编译错误。
  • 运行错误是指能够顺利的编译通过,在程序运行过程中产生的错误。例如:操作文件时文件无法找到,没有给对象开辟内存空间等。如果出现这样的错误,程序会停止运行,但是这样的错误,不容易被发现和排除。
  • java中的异常处理机制,为程序提供了清晰的异常终止和处理错误的接口。当异常发生时,发生异常的方法抛出一个封装了错误信息的异常对象。此时,程序不会继续运行,发生错误的方法也不会返回正常运行的值。异常处理机制开始搜索异常处理器来处理这种错误。
  • 异常(Exception)是一个在程序运行期间发生的事件。它会终端正在运行中的程序。Java中常见的异常包括 数组下标越界(ArrayIndexOfBoundsException)、空指针异常类(NullPointerException)、算术异常(ArithmeticException)、字符串转换为数字异常(NumberFormatException)、类型不存在异常(TypeNotPresentException)等。

2.异常的基本样式

与java异常处理的相关关键字包括try、catch、throw和finally等,异常的基本样式也使用这些关键字。

  • 基本样式:
methodname(){try{......				//可能产生异常的语句或方法程序块}catch(ExceptionType1 e){......		//对异常类型ExceptionType1对象的处理}catch(ExceptionType2 e){...... //对异常类型ExceptionType2对象的处理throw(e) //再抛出这个异常}finally {......//无论是否抛出异常,都需要执行的代码块
}
}

在方法内:

  • try语句内是用户监视的可能出现异常的程序语句和方法。
  • catch语句快内是用户对抛出异常对象的处理语句。
  • throw语句块内是手动抛出一个异常给函数method()的上级执行者,
  • finally语句块内,是必须在函数method()返回之前执行的代码。
    【例】异常处理简单示例
    在这里插入图片描述

3.java异常类

java异常类都是由Throwable类派生而来的。派生出的两个分支分别是Error类和Exception类。

3.1异常的层次结构

异常类是一种特殊类,表示的是一种特殊的运行错误,用于处理异常。在Java程序设计中,异常对象都是从Throwable类派生的实例。
在这里插入图片描述

  • error用于处理在运行过程中发生的系统内部错误和资源耗尽错误。
    应该尽量不出现Error类的错误。因为一旦出现了这样的错误,除了通知用户并使线程安全终止,用户也无能为力。
    通常Java程序不对Error类异常进行处理。并且这类错误也很少出现。
  • Exception类又分为多个分支,这些分支可以分为两类,一类是派生于RunTimeException的异常。一类是派生于IOException的异常,
    RunTimeException异常是由于程序错误导致的异常,IOException异常是本来可以正常运行的程序,在操作文件删除或者文件名修改等特殊情况下发生异常而导致程序不能正常运行。

派生于Throwable类的常用异常

被终止异常(InterruptedException)某个线程处于长时间的等待、休眠或其他暂停状态,其他线程通过Thread类的interrupt()方法终止该线程时抛出的异常
方法不存在异常(NoSuchMethodException)访问某个类的不存在方法时抛出的异常
找不到类异常(ClassNotFoundException)ClassNotFoundException 表示在尝试加载类时找不到该类。这可能发生在运行时,通常是由于类路径不正确或缺少相应的类文件
不支持克隆异常(CloneNotSupportedException)当没有实现Cloneable接口或者不支持克隆方法时调用其clone方法抛出该异常

派生于RuntimeException类的常用异常

算术运算异常(ArithmeticException)整数除0时抛出这个异常
类造型异常(ClassCstException)
数组越界异常(ArrayIndexOutofBoundsofException)
数组存储异常(ArrayStoreException)
访问空指针(NullPointException)

由IOException类派生的异常

文件已结束异常(EOFException)
文件未找到异常(FileNotFoundException)

3.2异常处理方法

【例】
在这里插入图片描述

4.异常捕获

企业针对产品的异常,会使用一些关键字进行描述和处理。如:产品平均无故障时间、产品故障率、召回等。java的异常处理是通过5个关键词来实现的。分别是try catch throw throws finally 。

其中,try用来存放可能发生一个或多个异常的Java语句,catch语句块用来捕获try语句块抛出的异常。finally语句块用来存放释放的资源和句柄等。

4.1 异常捕获处理语块

为了捕获异常,需要使用catch语句块来配合try语句块。
try语句块用来指定可能发生异常的程序块,配合使用的catch语句块用来处理try语句块抛出的异常。
try语句块内部如果出现异常,那么程序将跳过try语句块中出现的异常语句之后的其它代码,直接进入catch语句块内执行代码
【例】
在这里插入图片描述

try-catch 语句块可以嵌套使用。当try语句块遇到异常时,Java会检查与try异常程序块相配合的catch捕获处理中是否存在能处理该异常的catch语句块。如果存在,则该异常将被改catch语句块捕获并处理,否则,该异常将被上一级的try-catch语句块捕获。

【例】

package example;public class TrynestdealException {public static void main(String[] args) {tryCatch();						//调用静态try-catch函数}//静态tryCatch()函数static void tryCatch() {try {							//外层try块try {						//内层try块System.out.println("执行里层try块\n");int inte = Integer.parseInt("pencil");//字符串转化为整数System.out.println(inte);//输出整数}catch(ArrayIndexOutOfBoundsException e) {	//捕获异常System.out.println("执行里层catch块\n");System.out.println("捕获ArrayIndexOutOfBoundsException异常" + e.getMessage());}catch(ArithmeticException e) {	//捕获异常 ArithmeticException//捕获异常后输出异常信息System.out.println("执行里层catch2块\n");System.out.println("捕获ArithmeticException异常" + e.getMessage());}}catch(ClassCastException ie) {	//捕获异常ClassCastExceptionSystem.out.println("捕获外层异常ClassCastException" + ie.getMessage());}catch(NumberFormatException ie) {System.out.println("捕获外层异常NumberFormatException" + ie.getMessage());}}}

在这里插入图片描述

4.2 必须执行语句块

有时候我们要去某地,有多条交通路线,其中有一条是必须走的,也就是通常所说的交通要道。在try-catch-finally结构中,finally语句块就是交通要道。
在try-catch语句块中定义了finally语句块。这时无论try-catch语句块是否抛出和捕获异常,程序都将执行finally语句块。
【例】

package example;public class ExceptionFinally {public static void main(String[] args) {int num[] = new int[5];try {for(int i = 0;i<5;i++) {num[i]= i+1;for(int j = 0;i<=i;j++) {num[i]+= num[j];}}for(int i = 0;i<6;i++) {System.out.println(num[i]);}}catch(Exception e){e.printStackTrace();}finally {System.out.println("finally块是必经之路");}}}

在这里插入图片描述
在操作文件的时候,无论操作是否成功,必须要在程序运行后关闭文件。同样,如果将释放内存的工作放到finally语句块内,那么程序不会由于未释放资源而导致内存泄漏

4.3 必须执行语句块的意外

finally语句块通常情况下总是会被执行,但在下面这几种情况下finally语句块不会被执行

  • 电脑断电关机
  • 在finally语句块之前的语句中含有SYSTEM.EXIT(0)语句
  • 在finally语句块执行过程中抛出异常
  • 程序所属线程死亡,程序在未执行finally语句块之前就退出

在这里插入图片描述

5.异常抛出

异常捕获语句块都存在于产生异常的方法中,异常抛出可以将产生的异常抛给调用它的方法。
如果某方法的try语句块中抛出的异常没有与之匹配的catch块,或者catch语句块已经不活了异常但不想立即处理,就可以将异常抛给调用它的上一级方法。

5.1 异常抛出的概念

  • 在方法声明的时候,必须指定方法中可能产生的异常,使这个方法的调用者必须处理这些可能的异常。调用者可以自己处理这种异常,也可以将这种异常派送给它的调用者,因此异常可以逐级上溯。直到找到可以处理他的代码为止。
  • 抛出异常必须做的两部分工作是在方法的声明中使用throws语句指定它所抛出的异常和使用throw语句抛出异常。
  • 在方法中声明可能出现的异常是为了告诉编译器该方法可能产生的异常,因而要求该方法的使用者必须考虑处理方法抛出的异常,以增强程序的健壮性。
  • 任何有异常抛出的方法都有可能导致程序的崩溃,如果使用者没有对方法抛出的异常进行处理,则会导致程序运行结束。
  • 通过throw可语句可以明确的抛出一个异常,而在方法中使用throws声明次方法将抛出某种类型的异常。

5.2 throw

使用throw语句时必须声明一个异常对象,这个对象时Throwable派生类的对象
ThrowableInstance一定是Throwable类或Throwable子类的一个对象。简单类型(int、char)以及非Throwable类(String或Object)不能用作异常
【例】

package example;public class UseThrowExample {static void demoproc(String v1) {try {if(v1 == null) {//抛出NullPointerException异常throw new NullPointerException("Throw Example");}}catch(NullPointerException e){System.out.println("输入的参数为空");throw e;}}public static void main(String[] args) {try {String string = null;demoproc(string);		//调用方法}catch(NullPointerException e) {System.out.println("异常情况为"+ e);}}}

在这里插入图片描述

5.3 throws

如果一个方法可以导致一个异常但不处理它,那么他必须在方法声明时包含一个throws子句,以使方法的调用者库保护他们自己而不发生异常。
throws子句列举了一个方法可能引发的所有异常类型,一个方法引发的所有其他类型的异常必须在throws子句中生明。如果不这样做,会导致编译错误。

package example;import java.io.IOException;public class ThrowsUsingExample {public static void main(String[] args) {try {System.out.println("请输入字符");String s = getInput();System.out.println("输入字符为:");System.out.println(s);}catch(IOException e) {System.out.println("产生异常"+e.getMessage());}}private static String getInput() throws IOException{char[] buffer = new char[10];int count = 0;boolean flag = true;while(flag) {buffer[count] = (char)System.in.read();if(buffer[count]=='\n') {flag = false;}else {count++;}if(count >=10) {IOException aException = new IOException("buffer is null");throw aException;}}return new String(buffer);}}

在这里插入图片描述

5.4 抛出异常的步骤

我们在使用手机软件时,经常会遇到出现异常、卡顿或者异常退出的情况,这主要和开发软件异常处理或者手机内存不足等情况有关。程序抛出异常,一般分为以下三个步骤:

  • 确异常类
  • 创建异常类的实例
  • 抛出异常
package example;import java.sql.SQLException;public class ExceptionThreestep {//可能会抛出异常的方法public static void throwException() throws SQLException{try {throw new SQLException("SQLException1");}catch(SQLException e) {System.out.println("throwException:()抛出异常"+e.getMessage());//捕获异常暂不处理,抛出异常throw new SQLException("SQLException1");//抛出异常SQLException}}public static void main(String[] args) {try {throwException();}catch(SQLException e) {System.out.println("main()捕获SQLException:"+e.getMessage());}}}

在这里插入图片描述

6.自定义异常

除了Java中提供的一些异常类,还可以根据自己的需求定义异常类。

6.1 创建用户自定义异常

package example;class UserOwnException {//声明UserOwnException无参数构造方法public UserOwnException() {}//声明UserOwnException带有String类型参数的构造方法public UserOwnException(String smg) {super();//调用父类的构造方法}}public class UsingUserException {public static void main(String[] args) {try {execute();   //调用execute()方法}catch(UserOwnException e) {System.out.println(e.getMessage());}}static void execute() throws UserOwnException{try {throw new Exception();//抛出异常}//捕获Exception类catch(Exception e) {//捕获后,直接抛出用户自定义异常类throw new UserOwnException("自定义异常抛出"+e.getMessage());}}}

6.2 捕获运行时异常

创建自己的异常类,可以方便的处理和捕获某些运行时的异常,并重新抛出一个新的异常提供给它的调用者捕获。
运行时异常属于未检查异常,如果在方法的throws子句中声明了此异常,那么方法的调用者就可以不处理此异常。

package example;class MyArithException extends Exception{MyArithException(){}MyArithException(String msg){super(msg);	//调用父类的构造方法}
}public class CatchRunException {public static void main(String[] args) {try {executeRuntime();		//调用executeRuntime()方法}catch(MyArithException e){System.out.println("捕获运行时异常"+e.getMessage());}}static void executeRuntime() throws MyArithException{try {int i = 1/0;		//抛出运行时异常 ArithmeticException}catch(ArithmeticException e) { //捕获异常ArithmeticException/** 在这里捕获运行时异常ArithmeticException 不处理,* 而是抛出一个新的MyArithException 异常* 因为运行时异常不在方法声明的throws子句中声明* * */throw new MyArithException(e.getMessage());}}}

在这里插入图片描述

7.拓展训练

7.1 训练一:强制类型转换异常

【拓展要点:ClassCastException异常】
当程序运行时,有时需要对不同的类型进行类型转换。在进行类型转换的过程中,当java虚拟机发现这两个类型不兼容而无法完成转换时,就会出现ClassCastException异常

7.2 训练二:找不到类型时的异常

【拓展要点:ClassNotFoundException异常】
当应用试图根据字符串形式的类名构造类,而在遍历CLASSPATH之后做不到对应名称的.class文件时,将抛出ClassNotFoundException异常。

8.技术解惑

8.1 如何优雅地处理异常

异常是一种强大的调试手段,是因为回答了以下三个问题:

  • 为什么出了错 -------- 异常类型回答了“什么”被抛出
  • 在哪里出了错 ------- 异常堆栈回答了“在哪里”被抛出
  • 为什么出错 ------- 异常信息回答了“为什么”被抛出

三个原则可以帮助我们在调试过程中最大限度的使用好异常:

-具体明确 - 提早抛出 -延迟捕获

8.2 throw与throws的区别

(1)throw表示语句抛出一个异常。
一般用于程序出现某种逻辑时,程序员主动抛出某种特定类型的异常。
(2)throws是方法可能抛出异常的声明(在声明方法时,表示该方法可能要抛出异常)
当某个方法可能会抛出某种异常时,用throws声明可能抛出的异常,然后交给上层调用它的方法程序处理。

throw与throws关键字的比较

  • throws 出现在函数头部,throws出现在函数体中
  • throws表示出现异常的一种可能性,并不一定会发生异常;而throw表示抛出异常,执行throw一定会抛出某种异常对象
  • 两者都是消极处理异常的方式,而是抛出或者可能抛出异常。但是不会由函数去处理异常,而是由函数的上层调用进行处理

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

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

相关文章

本科且非专业学历|艺术自由职业者成功赴美国威斯康星大学麦迪逊分校自费访学

R老师只有本科学历且不是艺术专业&#xff0c;但有独创的艺术作品&#xff0c;其希望在一年的访问学者期间&#xff0c;拓宽艺术视野&#xff0c;同时学习艺术理论&#xff0c;以弥补学术背景薄弱的短板。最终我们为其落实了美国威斯康星大学麦迪逊分校访问学者职位。 R老师背景…

IAR stack usage

c - IAR Stack Usage for STM32 in the map File - Stack Overflow

SAP FICO 下载文件报错【调用数据提供商错误】

报错如下图所示&#xff1a; 解决办法&#xff1a; 当弹出保存文件的提示时&#xff0c;不要点击“记住我的决定”

【MATLAB】语法

MATLAB 基本语法(%{和%}) 赋值 函数名值&#xff1b;for for i1:10循环语句 end//while x0; sum0; while x<100sumsumx;x; end//if if x > 1f x^2 1; elsef 2 * x endswitch onum input(请输入一个数); switch num case -1 //注意case后面没有冒号disp(I am…

昇思25天学习打卡营第1天|基本介绍及快速入门

1.第一天学习总体复盘 1&#xff09;成功注册昇思大模型平台&#xff0c;并成功申请算力&#xff1b; 2)在jupyter环境下学习初学入门/初学教程的内容&#xff1b; 在基本介绍部分&#xff0c;快速撸了一边内容&#xff0c;有了一个基本的了解&#xff08;没理解到位的计划采用…

【尝鲜】SpringCloudAlibaba AI 配置使用教程

1、环境配置 maven依赖pom.xml 注意配置远程仓库&#xff0c;原因见&#xff1a;Unresolved dependency: ‘org.springframework.ai:spring-ai-core:jar:0.8.1’ <dependencies><!--Base--><dependency><groupId>org.springframework.boot</group…

用qq邮箱发送邮件验证码java

添加依赖 <dependency><groupId>com.sun.mail</groupId><artifactId>javax.mail</artifactId><version>1.6.2</version> </dependency>配置邮箱 实现代码 package com.example.demo.service; import org.springframework.st…

芜湖!恒驰大数据迁移案例荣幸亮相“东数西算”芜湖集群创新大会暨华为云华东(芜湖)数据中心全球开服活动

6月13日至14日&#xff0c;“东数西算”芜湖集群创新大会暨华为云华东&#xff08;芜湖&#xff09;数据中心全球开服活动在安徽芜湖隆重举办&#xff0c;标志着“东数西算”芜湖集群正式上线、华为云全国存算网的枢纽节点布局全面完成。 本次活动由华为技术有限公司主办、芜湖…

金属配件加工厂设备远程监控

随着科技的飞速发展&#xff0c;智能制造已成为制造业转型升级的重要方向。在金属配件加工领域&#xff0c;设备的稳定运行和高效管理对于提升产品质量、降低生产成本至关重要。HiWoo Cloud平台凭借其强大的远程监控功能&#xff0c;为金属配件加工厂提供了全新的解决方案&…

Android SurfaceFlinger——服务启动流程(二)

SurfaceFlinger 是 Android 系统中的一个核心服务&#xff0c;负责管理图形缓冲区的合成和屏幕显示&#xff0c;是 Android 图形系统的关键组件。 一、启动流程 SurfaceFlinger 作为一个系统服务&#xff0c;在 Android 启动早期由 init 进程通过 servicemanager 启动。它是作…

【黑马TS】学习资料Day4

五、在 React 中使用 TypeScript 现在&#xff0c;我们已经掌握了 TS 中基础类型、高级类型的使用了。但是&#xff0c;如果要在前端项目开发中使用 TS&#xff0c;还需要掌握 React、Vue、Angular 等这些库或框架中提供的 API 的类型&#xff0c;以及在 TS 中是如何使用的。 …

作为一名程序员,最大的成就感来自哪里?

说在前面 &#x1f388;作为一名程序员&#xff0c;我们的生活充满了挑战与创造。在成千上万行代码的背后&#xff0c;我们的成就感来源于何处&#xff1f;是解决问题的瞬间&#xff0c;是产品发布的一刻&#xff0c;还是用户的一声赞叹&#xff1f; 解决问题的瞬间 每当我们调…

AI写作平台:提升文档撰写效率的神器

工欲善其事&#xff0c;必先利其器。 随着AI技术与各个行业或细分场景的深度融合&#xff0c;日常工作可使用的AI工具呈现出井喷式发展的趋势&#xff0c;AI工具的类别也从最初的AI文本生成、AI绘画工具&#xff0c;逐渐扩展到AI思维导图工具、AI流程图工具、AI生成PPT工具、AI…

驱动层透明加密技术是什么?

驱动层透明加密技术的应用场景主要集中在确保数据在存储、传输和使用过程中的安全性&#xff0c;特别是在需要严格控制文件访问和防止数据泄露的场合。以下是几个具体的应用场景&#xff0c;结合参考文章中的相关信息进行归纳&#xff1a; www.weaem.com 内部文件流通&#xf…

【索引】数据库索引之顺序索引概述

目录 1、索引的基本概念 2、顺序索引 3、稠密索引和稀疏索引 3.1 什么是稠密索引&#xff1f; 3.2 什么是稀疏索引&#xff1f; 4、索引的更新 4.1 索引的插入操作 4.1 索引的删除操作 5、辅助索引 1、索引的基本概念 数据库中的索引与图书馆中书的索引作用相同&#xf…

Spire.PDF for .NET【文档操作】演示:如何删除 PDF 中的图层

借助Spire.PDF&#xff0c;我们可以在新建或现有pdf文档的任意页面中添加线条、图像、字符串、椭圆、矩形、饼图等多种图层。同时&#xff0c;它还支持我们从pdf文档中删除特定图层。 Spire.PDF for .NET 是一款独立 PDF 控件&#xff0c;用于 .NET 程序中创建、编辑和操作 PD…

【Python/Pytorch 】-- 滑动窗口算法

文章目录 文章目录 00 写在前面01 基于Python版本的滑动窗口代码02 算法效果 00 写在前面 写这个算法原因是&#xff1a;训练了一个时序网络&#xff0c;该网络模型的时序维度为32&#xff0c;而测试数据的时序维度为90。因此需要采用滑动窗口的方法&#xff0c;生成一系列32…

虚拟DOM的比较

patch 将虚拟DOM渲染成DOM&#xff0c;这就是patch的作用 在vue运行的时候会生成新旧两个虚拟DOM树&#xff0c;通过比较这两棵DOM树&#xff0c;我们就能针对性的修改真实DOM 事实上&#xff0c;我们大可以在每次比较两棵DOM树的时候删除现有的DOM结构&#xff0c;然后根据新的…

大数据-数据分析初步学习,待补充

参考视频&#xff1a;数据分析只需3小时从入门到进阶&#xff08;up亲身实践&#xff09;_哔哩哔哩_bilibili 数据指标&#xff1a; 对当前业务有参考价值的统计数据 分类&#xff1a;用户数据&#xff0c;业务数据&#xff0c;行为数据 用户数据 存量&#xff1a; DAU&#…

可信计算和数字水印技术

可信计算 可信计算可信计算基础概述可信计算关键技术要素可信性认证可信计算优劣 数字水印技术数字版权保护技术 可信计算 可信计算基础概述 可信计算&#xff08;Trusted Computing&#xff0c;TC&#xff09;&#xff1a;在计算和网络通信系统中广泛使用的、基于硬件安全模块…