




已阅读5页,还剩62页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1 第八章异常处理 Exception 8 1异常分类8 2引发异常8 3声明抛出异常8 4捕捉异常8 5定义自己的异常类型8 6构造方法与异常处理8 7小结 2 try catch finally语句 其语法格式 try 可能发生异常的代码 catch 异常类型1变量 异常的处理代码 catch 异常类型2变量 异常的处理代码 finally 总是要执行的代码 3 异常 例外 是方法代码运行时出现的非正常状态 这种非正常状态使程序无法或不能再正常地继续往下运行 常见的异常 数组下标越界除数为零内存溢出文件找不到等 4 运行机制 当一个方法在运行时发生异常时 将产生相应类型的一个异常对象 中止代码继续往下运行并寻找相应的异常处理代码 异常处理 1判断异常类型2产生对象3捕获处理异常 5 异常对象记录着这个异常的一些描述和状态信息 方法运行失败时 记录这个异常信息的异常对象将产生 或称为引发 抛出 throw 它有两种引发方式 1系统自动引发2在程序中由throw语句引发异常对象引发后 系统根据异常对象的类型 首先在当前方法寻找相应的异常处理代码 找到后就将控制流转入该异常处理代码并向其传递异常对象 称为捕获该异常 catch 异常处理代码可以根据接受到的异常对象进行相应的处理 6 寻找相应的异常处理代码的过程 当前方法直接或间接调用者找到 传递异常对象并进行异常处理没有找到 调用默认的异常处理程序 中止当前线程 7 举例 没有异常处理的情况 1 classExceptionDivideBy0 2 staticvoidmethod intx 0 z 10 inty 10 x System out println z z publicstaticvoidmain String args method System out println Aftermethod 11 8 Exceptioninthread main java lang ArithmeticException byzeroatExceptionDivideBy0 method ExceptionDivideBy0 java 4 atExceptionDivideBy0 main ExceptionDivideBy0 java 8 Pressanykeytocontinue 9 具有异常处理的情况 classExceptionDivideBy0 staticvoidmethod intx 0 z 10 try inty 10 x System out println z z catch ArithmeticExceptione System out println ArithmeticException System out println Aftertry catchblocks publicstaticvoidmain String args method System out println Aftermethod 10 ArithmeticExceptionAftertry catchblocks Aftermethod 11 每个异常由类Throwable或者它的一个子类的实例表示 这样的对象可被抛出并能被传递给合适的异常处理代码处理 Throwable类及其子类统称为异常类 每个异常类表示一种异常类型 Throwable类是Object类的直接子类 其本身又有两个直接子类 Error与Exception类 RuntimeException类是Exception类的直接子类 如图8 1所示 这里 Error类 RuntimeException类和Exception类分别代表某一类异常类型 8 1异常分类 12 图8 1异常类型及其分类 13 1 Error类及其子类 表示灾难性的 普通程序很难恢复的异常 例如 NoClassDefFoundError 类定义没找到异常 JVM无法找到相应的class文件 OutOfMemoryError 内存越界异常 JVM没有足够的存储空间满足对象创建的要求 NoSuchMethodError 调用不存在的方法异常 在改变某个方法的签名后 原先要调用该方法的应用程序 在运行时就会抛出该异常 一般情况下 程序员可不必理会这类异常 它们虽然很严重 但很少发生 14 2 RuntimeException类及其子类 表示设计或实现方面的问题 例如 ArithmeticException 算术运算异常 算术运算时发生的异常情况 如整数相除 除数为零 ClassCastException 强制类型转换异常 把一个对象引用转换成一个不合适的类型 如把一个对象引用转换成某个子类类型 NullPointerException 空引用异常 需要对象引用时使用了一个null引用 ArrayIndexOutOfBoundsException 数组下标越界异常 下标值超出了数组大小 NumberFormatException 数字格式异常 试图将非数字格式字符串转换成数值 15 3 Exception类及其非RuntimeException子类 表示运行时因环境的影响而引发的异常 例如 IOException 输入输出异常 在I O操作失败或者被中断时引发 其子类包括 EOFException FileNotFoundException InterruptedIOException等 InterruptedException 中断异常 当前等待或睡眠线程被其他线程中断时引发 这类异常并非因设计或实现引起 是无法避免的 但一般情况下 程序员应该提供相应的代码捕捉和处理 16 受检查的异常和不受检查的异常 受检查的异常Exception类及其非RuntimeException子类属于受检查的异常 受检查的异常要受编译系统的检查 如果一个方法可能会引发这类异常而又不能适当处理 那么应该用throws子句声明抛出 调用者或者用try catch语句捕捉处理 或者也用throws子句声明抛出 并由它的调用者处理 也就是说 对方法中可能会抛出的受检查异常 程序员必须捕捉处理或声明抛出 两者必选其一 否则编译系统将给出错误信息 17 受检查的异常和不受检查的异常 不受检查的异常 类Error和类RuntimeException及其子类属于不受检查的异常 如图8 1所示 不受检查的异常不受编译系统的检查 对这类异常 程序员可以捕捉或声明抛出 但通常可以不加理会 18 异常类的方法和属性 1 异常类的构造方法publicException 创建新异常 publicException Stringmessage 用字符串参数message描述异常信息创建新异常 2 异常类的方法publicStringtoString 返回描述当前异常对象信息的字符串 publicStringgetMessage 返回描述当前异常对象的详细信息 publicvoidprintStackTrace 在屏幕上输出当前异常对象使用堆栈的轨迹 即程序中先后调用了哪些方法 使得运行过程中产生了这个异常对象 19 所谓异常的引发是指因程序运行出现异常情况而产生异常对象 进而转入异常处理过程的情形 Java运行系统在发现异常情况时会自动引发异常 自动引发异常如下例 8 2引发异常 20 例8 1 在发生异常情况时由运行系统引发异常classDemo publicstaticvoidmain String args inta args length System out println a a intb 42 a int c 1 c 4 99 System out println Aftertry catchblocks 21 throw引发异常异常既可以在发生异常情况时由运行系统引发 也可以在程序中用throw语句显式引发 格式如下 thrownewArithmeticException 22 例8 2 下面程序在被减数a小于减数b时将引发ArithmeticException异常 1 classTest 2 staticintmethod inta intb 3 if a b 4 thrownewArithmeticException a b 产生异常5 returna b 6 7 publicstaticvoidmain String args 8 method 3 5 9 10 下面是该程序的输出结果 Exceptioninthread main java lang ArithmeticException a batTest method Test java 4 atTest main Test java 8 23 如果一个方法引发的是受检查的异常且自己没有捕捉 那么它必须用throws子句声明抛出 该方法的调用者如果不对异常进行捕捉 那么也必须用throws子句声明抛出 下面是包含throws子句的方法定义的语法格式 throws 8 3声明抛出异常 24 例8 3 下面程序与例8 2中的程序基本相同 只是method方法可能抛出的是一个受检查的Exception异常 但它既没有捕捉也没有声明抛出 所以是不能通过编译的 1 classTest 2 staticintmethod inta intb 3 if a b 4 thrownewException a b 5 returna b 6 7 publicstaticvoidmain String args 8 intr method 3 5 9 System out println r r 10 11 throwsException throwsException 25 对不受检查的异常 同样可以声明抛出 或进行捕捉 这在语法上是允许的 无论是受检查的异常还是不受检查的异常 对不受检查的异常 不管是否声明了异常抛出 异常一旦引发 其处理过程是一致的 即 异常沿着方法调用的反方向传播 寻找并转入合适的异常处理代码执行 如果方法及其所有的调用者都没有提供合适的处理代码 那么异常将最终传播到运行系统 运行系统调用默认的异常处理代码后终止程序执行 图8 2说明了例8 2和例8 3中异常引发和传递的过程 26 图8 2异常传播过程示意图 27 回忆超类和子类中方法覆盖的要求 两个方法具有相同的方法签名 即方法名和方法的参数完全一致 返回类型相同覆盖方法的访问级别不能低于被覆盖方法的访问级别覆盖方法 子类方法 不能比被覆盖方法 超类方法 抛出更多类型的受检查异常 下面通过例子加以说明 28 例8 4 有以下类定义 1 importjava io 2 3 classTestClass4 voidtestM BaseClasso throwsIOException5 o method 7 8 9 classBaseClass10 voidmethod throwsIOException11 12 29 请问下面哪些BaseClass类的子类定义是合法的 A classAextendsBaseClass voidmethod throwsIOException B classBextendsBaseClass voidmethod throwsException C classCextendsBaseClass voidmethod throwsEOFException FileNotFoundException 30 D classDextendsBaseClass voidmethod throwsIOException InterruptedException E classEextendsBaseClass voidmethod F classFextendsBaseClass voidmethod throwsIOException NullPointerException 31 例2 10 从键盘输入一个整数和实数 并输出它们的和 importjava io 引入java io包classInputDemo publicstaticvoidmain Stringargs throwsIOException 用标准输入System in创建一个BufferedReaderBufferedReaderbr newBufferedReader newInputStreamReader System in System out print 请输入一个整数 Stringstr br readLine 输入字符行存入字符串inti Integer parseInt str 转换字符串为整型数据 32 System out print 请输入一个实数 str br readLine floatf Float parseFloat str System out print 它们的和是 i f 33 如果不加以捕捉 引发的异常将沿着方法调用的反方向往外抛出和传播 直至Java运行系统 通常 这并不是所希望的结果 一般来说 引发异常的方法的调用者应该捕捉 并根据具体情况处理异常 从而阻止异常继续往外传播 Java使用try catch finally语句来捕捉和处理可能发生的异常 该语句的语法格式如下 8 4捕捉异常 34 try 此处是可能发生异常的代码 catch 异常的处理代码 catch 异常的处理代码 finally 总是要执行的代码 该语句包含try catch和finally三个子句 其中 catch子句可以有多个 而且至少有一个catch子句或finally子句 35 try子句包含一段可能要发生异常的代码 一旦发生异常 将由后面的catch子句捕捉处理 每个catch子句有一个参数 参数类型指明该子句能够捕捉的异常类型 如果子句指定的参数类型是所发生的异常的类或者是其超类 则说明catch子句能够捕捉该异常 此时 运行系统将把异常对象的引用值传递给catch子句的参数变量 并将控制流转移到该catch子句 执行子句内的异常处理代码 之后 接着执行try语句后面的代码 如果try子句内的代码没有发生任何异常 那么跳过catch子句 直接执行try语句后面的代码 8 4 1try和catch子句 36 classDemo publicstaticvoidmain String args try inta args length System out println a a intb 42 a int c 1 c 4 99 catch ArithmeticExceptione 捕获算术运算异常 System out println Divideby0 e catch ArrayIndexOutOfBoundsExceptione System out println Arrayindexoob e System out println Aftertry catchblocks 例8 5 try和catch子句举例 37 a 0Divideby0 java lang ArithmeticException byzeroAftertry catchblocks 38 最后说明两点 1 当发生异常时 如果有catch捕捉到了异常 那么不管具体的异常处理代码如何 甚至不含任何语句 Java运行系统都认为该异常已被消除 2 当执行完异常处理代码后 控制流并不会回到异常发生处 而是执行try语句后面的代码 如果没有finally子句 39 try子句内的代码可能会发生多种类型的异常 而try语句也允许有多个catch子句 每个catch子句可以捕捉一种类型 包括子类型 的异常 当然 每次执行try语句时 至多只能抛出一个异常 相应地 至多只能有一个异常处理代码被执行 8 4 2多个catch子句 40 当异常发生时 运行系统将按先后次序依次判断各catch子句 如果发现某个catch子句能够捕捉该异常 就执行其中的处理代码 而其后面的catch子句将被忽略 注意 处理子类型异常的catch子句一定要放在处理超类型异常的catch子句之前 如果将一个处理超类型异常的catch子句放在处理子类型异常的catch子句之前 或者两个catch子句捕捉同一类型的异常 编译系统都将给出错误信息 41 publicclassTest2 publicstaticvoidmain String args intx 0 inty try y 100 x catch Exceptionex ex printStackTrace catch ArithmeticExceptionex ex printStackTrace ArithmeticExceptionex Exceptionex 42 使用finally子句的好处是 控制流不管以何种原因离开try语句 都要先执行finally子句 所以 可以将那些无论是否发生异常 异常无论是否被捕捉都需要执行的代码放置在finally子句内 8 4 3finally子句 43 控制流离开try语句的情况可分为以下几种 try子句代码正常执行 没有引发异常 try子句代码执行时引发异常 但被catch子句捕捉处理 try子句代码执行时引发异常 但没有catch子句能捕捉处理 try子句代码执行时引发异常 且被catch子句捕捉 但在执行异常处理代码时发生新的异常 注意 因return break或continue等跳转语句 不管是出现在try子句中 还是出现在catch子句中 要离开try语句时 同样需要先执行finally子句 44 1 classFinallyDemo 2 staticvoidm1 inti 3 try 4 if i 2 5 System out println 第2种情况 发生算术运算异常 6 thrownewArithmeticException 7 if i 3 8 System out println 第3种情况 发生数字格式异常 9 thrownewNumberFormatException 10 if i 4 11 System out println 第4种情况 发生数组下标越界异常 12 thrownewArrayIndexOutOfBoundsException 13 14 System out println 第1种情况 没有发生异常 15 例8 9 finally子句举例 45 15 catch ArithmeticExceptione 16 System out println 异常被捕捉处理 17 catch ArrayIndexOutOfBoundsExceptione 18 System out println 异常被捕捉 但又被重新引发 19 throwe 20 finally21 System out println 这是finally子句 23 System out println 这是try语句后的代码 24 25 publicstaticvoidmain Stringargs 26 for inti 1 i 5 i 27 try28 m1 i 29 catch RuntimeExceptione 30 System out println 由main方法捕捉到异常 46 下面是程序的输出结果 第1种情况 没有发生异常这是finally子句这是try语句后的代码第2种情况 发生算术运算异常异常被捕捉处理这是finally子句这是try语句后的代码 47 下面是程序的输出结果 续 第3种情况 发生数字格式异常这是finally子句由main方法捕捉到异常第4种情况 发生数组下标越界异常异常被捕捉 但又被重新引发这是finally子句由main方法捕捉到异常 48 当try子句发生异常时 如果没有一个catch子句能够捕捉到 则异常从该try语句抛出并向外传播 如果try语句本身是另外一个try语句的try子句的一部分 那么异常就由该外层try语句的catch子句捕捉处理 如果没有外层的try语句 或者外层try语句也没有catch子句能够捕捉该异常 则异常被传播到方法的调用者那里 由调用方法处理 8 4 4未捕捉到的异常 49 1 classTest 例8 7未捕捉到的异常被传播并由调用方法捕捉 2 staticvoidm1 Strings 3 try4 intx Integer parseInt s 5 inty 10 x 6 catch NumberFormatExceptione 7 System out println caught e inm1 8 System out println exitingfromm1 9 10 publicstaticvoidmain Stringargs 11 try12 m1 args 0 13 catch ArrayIndexOutOfBoundsExceptione 14 System out println caught e inmain 15 catch ArithmeticExceptione 16 System out println caught e inmain 17 System out println exitingfrommain 18 50 该程序可以在不同情况下发生3种不同类型的异常 如果命令行不提供参数 下面是程序的输出结果 C javaTestcaughtjava lang ArrayIndexOutOfBoundsException 0inmainexitingfrommain如果命令行的第1个参数为非数字格式字符串 下面是程序的输出结果 C javaTestaaacaughtjava lang NumberFormatException aaainm1exitingfromm1exitingfrommain如果命令行的第一个参数为数字0 下面是程序的输出结果 C javaTest0caughtjava lang ArithmeticException byzeroinmainexitingfrommain 51 try子句发生的异常可以由语句中的某个catch子句捕捉处理 但在执行catch子句内的异常处理代码时也可能再引发新的异常 此时 原先的异常被遗弃 新的异常从try语句抛出并向外传播 与 未捕捉到的异常 类似 该新异常或者由外层try语句的catch子句捕捉 或者由方法的调用者处理 8 4 5再引发异常 52 1 importjava io IOException 例8 8 再引发异常举例2 classTest 3 staticvoidm1 throwsIOException 4 try5 thrownewRuntimeException demo 1 6 catch RuntimeExceptione 7 System out println caught e inm1 8 thrownewIOException demo 2 9 10 publicstaticvoidmain Stringargs 11 try12 m1 13 catch IOExceptione 14 System out println caught e inmain 15 System out println exitingfrommain 16 17 53 下面是程序的输出结果 caughtjava lang RuntimeException demo 1inm1caughtjava io IOException demo 2inmainexitingfrommain 54 8 5定义自己的异常类型自定义的异常类型必须是Throwable类的子类 只有Throwable类及其子类的实例才能够被引发和捕捉 通常将自定义异常类型定义成Exception的子类 以产生受检查的异常 Java异常处理机制的特点是方法的调用者必须认识和处理方法可能会抛出的受检查异常 而对不受检查的异常 调用者则可以不加理会 55 例 在定义银行类时 若取钱数大于余额则作为异常处理 InsufficientFundsException 思路 产生异常的条件是余额少于取额 因此是否抛出异常要先判断该条件 确定产生异常的方法 应该在取钱方法withdrawal中产生异常InsufficientFundsException 处理异常安排在调用withdrawal的时候 因此withdrawal方法要声明异常 由上级方法捕获并处理 要定义好自己的异异常 56 publicclassInsufficientFundsExceptionextendsException privateBankexcepbank privatedoubleexcepAmount InsufficientFundsException Bankba doubledAmount excepbank ba excepAmount dAmount publicStringtoString Stringstr Thebalance excepbank getbalance Thewithdrawalwas excepAmount returnstr 57 classBank doublebalance 余额publicvoiddeposite doubledAmount 存钱 if dAmount 0 0 balance balance dAmount publicvoidwithdrawal doubledAmount throwsInsufficientFundsException 取钱if balance dAmout thrownewInsufficientFundsException this dAmount balance balance dAmount publicdoublegetbalance 获取余额 returnbalance 58 publicclassExceptionDemo publicstaticvoidmain Stringargs try Bankba newBank ba deposite 50 ba withdrawal 100 System out println Withdrawalsuccessful catch Exceptione System out println e toString 59 例 设计自己的异常 从键盘输入一个double类型的数 若不小于0 0 则输出它的平方根 若小于0 0 则输出提示信息 输入错误 importjava io classMyExceptionextendsException doublex MyException doublex this x x publicStringtoString return 输入错误 x 0 0 x x 60 publicclassMySqrt staticvoidtest doublex throwsMyException if x 0 0 thrownewMyException x elseSystem out println Math sqrt x publicstaticvoidmain Stringargs throwsIOException try System out print 求输入实数的平方根 请输入一个实数 BufferedReaderbr newBufferedReader newInputStreamReader System in Strings br readLine test Double parseDouble s catch MyExceptionClasse System out println e toString 61 与普通方法一样 构造方法也可以引发异常 捕捉异常或者声明抛出异常 实际上 构造方法有时比普通方法更需要使用异常处理机制 对于普通方法 有时可以通过返回一个特殊值来表示其执行出现了异常 例如 一个方法的返回类型是一种引用类型 且在正常情况下它总是能返回一个对象的引用
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安徽公务员的考试题目及答案
- 医疗质量安全核心制度考试试题附答案(B卷)
- 2025年成人教育领域线上学习模式下的在线教育市场细分与定位研究
- 2025年老年健康管理长期照护服务模式与护理团队协作研究报告001
- 2025年电商平台售后服务与品牌形象塑造研究报告
- 河北张家口2025年公开招聘农村党务(村务)工作者笔试题带答案分析及完整答案详解1套
- 国企企业面试题库及完整答案详解【易错题】
- 考点解析-河南省登封市中考数学真题分类(实数)汇编单元测试试题(详解版)
- 2025年度票据保险与损失补偿服务合同
- 2025版汽车销售与保险组合合同范本
- T/ZHCA 007-2019染发化妆品眼刺激性试验体外测试方法牛角膜浑浊和渗透性试验
- 电梯砝码租凭合同协议书
- 基于人工智能的性传播疾病预防个性化方案研究-洞察阐释
- (高清版)DG∕TJ 08-2093-2019 电动汽车充电基础设施建设技术标准 含2021年局部修订
- 《原发性肝癌诊疗指南(2024年版)》解读课件
- 私人诊所免责协议书
- 三年级数学下册计算题专项练习大全(每日一练共22份)
- 蒸汽锅炉试题及答案
- 2025-2030羽毛球产业规划专项研究报告
- 儿童合唱教学课件
- 2024年中国农业银行西藏日喀则支行春季校招笔试题带答案
评论
0/150
提交评论