版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第六章异常处理本章主要内容异常概述异常处理机制Checked异常和Runtime异常使用throw抛出异常Java的异常跟踪栈异常处理规则程序中的错误可分为三类:编译错误、逻辑错误和运行时错误。
编译错误是由于没有遵循Java语言的语法规则而产生的,这种错误要在编译阶段排除,否则程序不可能运行。
逻辑错误是指程序编译正常,也能运行,但结果不是人们所期待的。异常(Exception)又称为例外,是指在程序运行过程中发生的非正常事件,这些事件的发生会影响程序的正常执行。①用户输入出错②所需文件找不到③运行时磁盘空间不够④内存不够
⑤算术运算错(数的溢出,被零除…)⑥数组下标越界......什么是异常?异常对象在Java语言中,我们用异常对象来表示不同的异常。所谓Java异常对象就是一个存放着相关错误信息的对象,如果方法运行时产生了异常,该方法就可以抛出一个异常对象为了表示不同种类的异常,Java语言中定义了许多异常类。为什么要处理异常?异常处理机制是JAVA语言的重要特征之一。通过异常处理机制可防止程序执行期间因出现错误而造成不可预料的结果。一个好的应用程序,除了具备用户要求的功能外,还要求能预见程序执行过程中可能产生的各种异常,并把处理异常的功能包括在用户程序中。在Java程序运行过程中,产生的异常通常有三种类型:一是JAVA虚拟机由于某些内部错误产生的异常,这类异常不在用户程序的控制之内,也不需要用户处理这类异常;二是标准异常类,由java系统预先定义好的。这类异常是由程序代码中的错误而产生的,如:以零为除数的除法,访问数组下标范围以外的数组元素,访问空对象内的信息,这是需要用户程序处理的异常。三是根据需要在用户程序中自定义的一些异常类。异常的类型Java中所有的异常都是用类表示的,在JAVA中预定义了很多异常类,每个代表了一种类型的运行错误。当程序发生异常时,会生成某个异常类的对象。Java解释器可以监视程序中发生的异常,如果程序中产生的异常与系统中预定义某个异常类相对应,系统就自动产生一个该异常类的对象,就可以用相应的机制处理异常,确保程序能够安全正常地继续运行。异常对象中含有这种运行错误的信息和异常发生时程序的运行状态。Java异常处理的特点Java中标准异常类的层次结构
针对各种类型的异常,Java定义了许多标准异常类,所有的Java异常类都是系统类库中的Exception类的子类,它们分布在java.lang、java.io、java.util和包中。每个异常类对应一种特定的运行错误,各个异常类采用继承的方式进行组织。异常类的层次结构图如下图所示:在Java语言中,任何的异常对象都是Throwable类的直接子类或间接子类的实例。Java的类库已经提供了一些常见的异常类,如果这些异常类不能够满足要求,用户也可以创建自己的异常类。Java中异常类的层次结构Throwable类有两个直接子类:Error(致命错误)和Exception(异常)。Error类型的异常与JAVA虚拟机本身发生的错误有关,这类异常由java直接处理,用户程序一般不能太做什么,只能等待系统通知用户关闭程序。用户程序产生的错误由Exception的子类表示。用户程序应该处理这类异常。1、Throwable类该类属于Java.lang包,是所有异常类的父类.在Throwable类中定义了描述异常发生的位置和所有异常类共同需要的内容.
publicThrowable(Stringmessage)以message的内容作为错误信息串创建Throwable对象,同时调用该对象的另一方法fillInStackTrace。publicThrowable()以null作为错误信息串内容创建Throwable对象,同时调用该对象的另一方法fillInStackTrace记录异常发生的位置。Throwable类的主要成员函数publicStringgetMessage()如果创建当前对象时以message的内容作为错误信息串,本方法返回串变量message的内容;若创建当前对象时未使用参数则返回null。publicStringtoString()
若当前对象包含错误信息,本方法返回的字符串由三部分组成:当前对象的类名,一个冒号和一个空格,错误信息的字符串;若当前对象未包含错误信息则仅返回当前对象的类名。publicvoidprintStackTrace()将跟踪栈中的信息输出,输出的第一行是当前对象toString()的返回值,其余各行是跟踪栈中的信息。publicTrowablefillInStackTrace()将当前异常对象的发生位置(类、方法和所在文件的行号)记录到跟踪栈对象中。Error类是Throwable类的子类,由系统保留,用户不能使用。也就是说,Error类型的错误不允许用户插手处理,由Java系统自行处理。Error类描述系统错误:如将字节码装入内存的过程中和对字节码进行检查的过程中遇到的问题、java的内部错误、资源耗尽的情况。这类异常由java直接处理,用户程序不要理会这类异常。2、Error类
Exception类是Throwable类的子类,用户程序中可以直接使用Exception类处理Exception类型的异常。Exception类不仅继承了Throwable类的方法,同时定义以下两个构造函数:
publicException()publicException(Strings)说明:字符串s用来接收传入的字符串信息,该信息通常是对错误的描述。3、Exception类必检异常与非必检异常RuntimeException类及其子类被称为“运行时异常”一般发生在JRE内部也称“非必检异常”如NullPointerException其他异常被成为“非运行时异常”一般发生在JRE外部也称“必检异常”如IOException异常程序举例://java直接处理运行时异常classTestSystemException{publicstaticvoidmain(String[]args){int
num[]=newint[2];for(inti=1;i<3;i++){num[i]=i;System.out.println(“num[”+i+”]=”+i);}}}该程序产生的输出见程序的运行.Java对异常的处理涉及两方面的内容:一是抛出(throw)异常二是捕捉(catch)异常如果程序在运行过程中出现了运行错误,并且产生的异常与系统中预定义某个异常类相对应,系统就自动产生一个该异常类的对象,这个过程称为抛出(throw)异常。当有异常对象抛出时,将在程序中寻找处理这个异常的代码,如果找到处理代码,则把异常对象交给该段代码进行处理,这个过程称为捕捉(catch)异常。如果程序中没有给出处理异常的代码,则把异常交给Java运行系统默认的异常处理代码进行处理。默认的处理方式是:首先显示描述异常信息的字符串,然后终止程序的运行。
异常的处理机制异常的抛出(throw)抛出异常有两种方式:由系统自动抛出和利用抛出语句抛出。1由系统自动抛出异常在程序运行过程中,如果出现了可被Java运行系统识别的错误,系统会自动产生与该错误相对应的异常类的对象,即自动抛出。例如上例。2人为异常抛出两种方式:①在方法头写出需要抛出的异常(利用throws语句)②在方法体内抛出异常(利用throw语句)Throws语句抛出异常格式
修饰符返回值类型方法名([形参表])throws异常类名1,异常类名2,……{……}说明:在执行该方法的过程中,如果出现了由throws列出的异常,则可以抛出异常,并在程序中寻找处理这个异常的代码;如果程序中没有给出处理异常的代码,则把异常交给Java运行系统默认的异常处理代码进行处理。Throws语句举例classThrows_Exp{publicstaticvoidmain(String[]args)throwsArithmeticException,ArrayIndexOutOfBoundsException{inta=4,b=0,c[]={1,2,3,4,5};System.out.println(a/b);System.out.println(c[a+1]);System.out.println(“end”); }}Throw语句抛出异常
如果需要在方法内某个位置抛出异常,可以使用Throw语句,通常将Throw语句和if语句配合使用。格式:①throw异常类对象名②throw(new异常类名());说明:
执行throw语句时,程序终止执行后面的语句,在程序中寻找处理异常的代码;如果程序中没有给出处理代码,则把异常交给Java运行系统处理。Throw语句举例1classThrow_Exp1{publicstaticvoidmain(String[]args){ArithmeticExceptione=newArithmeticException();inta=4,b=0;System.out.println(“BeforeArithmeticException”);if(b==0)throwe;System.out.println(a/b); }}
Throw语句举例2classThrow_Exp2{publicstaticvoidmain(String[]args){inta=5,c[]={1,2,3,4,5};System.out.println(“BeforethrowArrayIndexOutOfBoundsException”);if(a>4)throw(newArrayIndexOutOfBoundsException());System.out.println(“AfterthrowArrayIndexOutOfBoundsException”); }}Throw语句举例3classThrow_Exp3{publicstaticvoidmain(String[]args){inta=5,b=0,c[]={1,2,3,4,5};System.out.println(“Beforethrow”);if(b==0)throw(newArithmeticException());System.out.println(a/b);if(a>4)throw(newArrayIndexOutOfBoundsException());System.out.println(a/b);}}
捕捉异常在前面给出的例子中,由于程序中都没有给出处理异常的代码,因此抛出的异常都被Java运行系统捕捉,由Java运行系统进行相应处理。一般来说,在设计程序过程中,如果能够预测程序中可能发生的异常,则应在程序中给出处理代码。而不交给Java运行系统处理,对于程序中那些不能预测的异常,可交给Java运行系统处理。要由程序自己捕捉和处理异常,需要建立try-catch-finally语句块。try-catch语句块格式:try{//在此区域内或能发生异常;}catch(异常类1e1){//处理异常1;} …catch(异常类nen){//处理异常n;}[finally{//不论异常是否发生,都要执行的部分;}]被监视的块该catch子句能够捕捉和处理的异常类型(1)将可能发生异常的程序代码放置在try程序块中。如果该块内的代码出现了异常,系统将终止try块代码的执行,自动跳转到所发生的异常类对应的catch块中,执行该块中的代码。如果程序运行正常,后面的各catch块不起任何作用。(2)finally块是个可选项,无论异常是否发生,finally块的代码必定执行。通常把对各种异常共同处理部分放在finally块中,如输出统一信息、释放资源、清理内存、关闭已打开的文件等。(3)一个try块可以对应多个catch块,用于对多个异常类进行捕获。但最多只能选中一个执行。(4)异常对象与catch块中声明的实例的匹配原则: 异常对象是catch块中声明的异常类的实例;
异常对象是catch块中声明的异常类的某一子类的实例; Try-catch-finally结构说明:try-catch-finally执行过程当try块中的某条代码抛出异常时:首先,自该语句的下一条语句起的所有try块中的剩余语句将被跳过不予执行;其次,程序执行catch子句进行异常捕获,异常捕获的目的是进行异常类型的匹配,并执行与所抛出的异常类型相对应的catch子句中的异常处理代码。需要注意的是:如果try块中没有任何的异常抛出,则所有的catch子句将会被跳过;如果try块中所抛出的异常对象类型与所有的catch子句中的所声明的异常类型都不匹配,则方法会立即中止,并将该异常对象继续抛出,沿调用堆栈传递。try-catch-finally执行过程当一个方法的某条语句抛出异常后,该方法剩余的语句将无法继续执行。这种情况下,方法往往无法将其占用的资源进行释放。解决方法:在每个catch子句的异常处理代码中也加上资源释放的代码,但这种方法非常麻烦;Java语言的异常处理机制中提供了一个更好的方案-程序员可以使用finally子句来统一进行资源释放之类的工作。try-catch-finally执行过程不论try块中的代码是否抛出异常及异常是否被捕获,finally子句中的代码一定会被执行:如果try块中没有抛出任何异常,当try块中的代码执行结束后,finally中的代码将会被执行;如果try块中抛出了一个异常且该异常被catch正常捕获,那么try块中自抛出异常的代码之后的所有代码将会被跳过,程序接着执行与抛出异常类型匹配的catch子句中的代码,最后执行finally子句中的代码。如果try块中抛出了一个不能被任何catch子句捕获(匹配)的异常,try块中剩下的代码将会被跳过,程序接着执行finally子句中的代码,未被捕获的异常对象继续抛出,沿调用堆栈顺序传递。try-catch-finally执行过程try-catch-finally语句举例1classTry_Catch_Exp1{publicstaticvoidmain(String[]args){intd=0,a;
try{System.out.println("BeforethrowException");a=5/d;System.out.println("theExceptionisthrow,Thestatementis'trun");}
catch(ArithmeticExceptione){
System.out.println("处理算数异常的catch语句块捕获了异常!"); System.out.println("捕获的异常为"+e);}
catch(ArrayIndexOutOfBoundsExceptione){System.out.println("处理数组下标越异常的catch语句块捕获了异常!"); System.out.println("捕获的异常为"+e);}
finally{System.out.println("这是所有catch块的共有部分!");}System.out.println("try-catch-finally块后面的语句");}}
try-catch-finally语句举例2classTry_Catch_Exp2{publicstaticvoidmain(String[]args){inta=5,b=0,c[]={1,2,3,4,5};
try{ System.out.println("Beforethrow");if(a>4)throw(newArrayIndexOutOfBoundsException());System.out.println("Afterthrow");}
catch(ArrayIndexOutOfBoundsExceptione){System.out.println("处理数组下标越异常的catch语句块捕获了异常!"); System.out.println("捕获的异常为"+e);}
finally{System.out.println("这是所有catch块的共有部分!");}System.out.println("try-catch-finally块后面的语句");}}
try-catch-finally语句举例3publicclassExampleOfException{String[]lines={"Thefirstline","Thesecondline","Thelastline"};publicstaticvoidmain(String[]args){ExampleOfExceptioneoe=newExampleOfException();eoe.methodA();
System.out.println("Programfinished.");}...voidmethodC(){for(inti=0;i<4;i++){try{System.out.println(lines[i]);}catch(ArrayIndexOutOfBoundsExceptione){System.out.println("Re-settingIndexValue");}}}}example上面的例子中可能会产生数组越界异常,所以将其置于try块中,并在catch子句中对ArrayIndexOutOfBoundsException类型的异常进行捕获,并进行处理。如果try块中可能抛出多个类型的异常,程序员可以使用多个catch子句对这些异常进行捕获,每种异常类型对应一个单独的catch子句。需要注意的是,这些catch子句是顺序执行的。这意味着,异常对象总是被第一个catch子句首先捕获,如果类型不匹配,才会执行下一个catch子句。读者可以试着分析下面的程序片断,看看有什么样的问题存在。问题当调用上述方法m()时,try块中包含方法的return语句,返回值为1。然而,实际调用该方法后产生的返回值为0。这是因为在方法实际返回并结束前,finally子句中的内容无论如何要被执行,所以finally子句中的return语句使得该方法最终实际返回值为0。publicintm(){try{ return1;}finally{ return0;}}用户自定义的异常类
尽管Java提供了很多异常类,但用户还是可以根据需要定义自己的异常类,即创建自定义异常类。
说明:(1)用户自定义的异常类必须是Throwable类或Exception类的子类。(2)自定义的异常类,一般只要声明两个构造方法,一个是不用参数的,另一个以字符串为参数。作为构造方法参数的字符串应当反映异常的信息。其一般形式为:class自定义异常类名extendsException{
异常类体;}用户自定义的异常类格式:自定义异常类classMyExceptionextendsException{…}用户定义的异常同样要用try--catch捕获,但必须由用户自己抛出thrownewMyException().用户自定义的异常类举例:classException_exp{ publicstaticvoidmain(String[]args){ try{System.out.println("2+3="+add(2,3)); System.out.println("-8+10="+add(-8,10));} catch(Exceptione){System.out.println("Exceptionis"+e);}}staticintadd(intn,intm)throwsUserException{ if(n<0||m<0)thrownewUserException();returnn+m;}}
classUserExceptionextendsException{ UserException(){super("数据为负数");}}Java的异常跟踪栈main()methodA()methodB()methodC()调用Java程序在执行的过程中,形成了一个先进后出的调用堆栈,各方法之间依照调用先后的不同,由先至后的进入调用堆栈,堆栈的最上层即是当前被调用执行的方法。该方法执行完毕后,会将处理器控制权交还给调用他的方法,依此类推。方法调用堆栈方法调用堆栈中异常对象的传递
当某一方法中的一个语句抛出一个异常时,如果该方法中没有处理该异常的语句,那么该方法就会中止执行,并将这个异常传递给堆栈中的下一层方法,直到某一方法中含有处理该异常的语句为止。如果该异常被传递至主方法,而主方法中仍然没有处理该异常的语句,则异常将会被抛至JVM,程序中断。main()methodA()methodB()methodC()调用传递实例publicclassExampleOfException{String[]lines={"Thefirstline","Thesecondline","Thelastline"};publicstaticvoidmain(String[]args){ExampleOfExceptioneoe=newExampleOfException();eoe.methodA();
System.out.println("Programfinished.");}voidmethodA(){methodB();}voidmethodB(){methodC();}voidmethodC(){
for(inti=0;i<4;i++)System.out.println(lines[i]);}}
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 神经外科低钠血症治疗指南
- 风带来的好处和坏处活动
- 企业班组安全教育
- 第六章 机械能守恒定律-功和功率 2025年高考物理基础专项复习
- 示出塞课件教学课件
- 3.1.1 铁及其化合物 课件 上学期化学人教版(2019)必修第一册
- 慢病专员工作汇报
- 吉林省2024七年级数学上册第2章整式及其加减期末提分课件新版华东师大版
- 常见的安全标志教案及反思大班
- 氧化碳的说课稿
- WB/T 1060-2016道路运输食品冷藏车功能选用技术规范
- JJF 1659-2017PM2.5质量浓度测量仪校准规范
- GB/T 3766-2001液压系统通用技术条件
- GB/T 23114-2008竹编制品
- GB 30603-2014食品安全国家标准食品添加剂乙酸钠
- 松下panasonic-视觉说明书pv200培训
- 2023届台州一模考试试卷
- 大学物理 电阻电路等效变换
- 国企职务犯罪预防课件
- 介入手术跟台课件
- 《子路、曾皙、冉有、公西华侍坐》 课件46张
评论
0/150
提交评论