第6章 异常处理_第1页
第6章 异常处理_第2页
第6章 异常处理_第3页
第6章 异常处理_第4页
第6章 异常处理_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第六章异常处理1【学习目标】1.了解什么是错误和异常。2.熟悉异常对象类型和异常处理机制。3.掌握异常处理的编程技术。4.能够建立自己的异常类。2异常是导致程序中断运行的一种指令流,如果不对异常进行正确的处理,则可能导致程序的中断执行,造成不必要的损失,所以在程序的设计中必须要考虑各种异常的发生,并正确地做好相应的处理,这样才能保证程序正常地执行。在JAVA中一切的异常都秉着面向对象的设计思想,所有的异常都以类和对象的形式存在,除了JAVA中已经提供的各种异常类外,用户也可以根据需要定义自己的异常类。任何程序都可能存在问题。在程序实际的应用中,可能存在大量的未知问题,所以在程序的开发中对于错误的处理是极其重要的。任何程序都很难做到百分百完美,所以程序开发中一定要对各种问题进行处理,而JAVA提供的异常处理机制可以帮用户更好地解决这方面的问题。3在没有异常处理的语言中如果要回避异常,就必须使用大量的判断语句,配合所想到的错误状况来捕捉程序中所有可能发生的错误。但为了捕捉这些错误,编写出来的程序代码经常有大量的判断语句,有时这样也未必能捕捉到所有的错误,而且这样做势必导致程序运行效率的降低。JAVA的异常处理机制恰好改进了这一点。它具有易于使用、可自行定义异常类、处理抛出的异常同时又不会降低程序运行的速度等优点。因而在JAVA程序设计时,应充分地利用JAVA的异常处理机制,以增进程序的稳定性及效率。46.1异常概述一、错误与异常根据错误性质将运行错误分为两类:错误和异常。

1.致命性的错误

如程序进入了死循环,或递归无法结束,或内存溢出,这类现象称为错误。

2.非致命性的异常

如运算时除数为0,或操作数超出数据范围,或打开一个文件时,发现文件并不存在,或欲装入的类文件丢失,或网络连接中断等,这类现象称为异常。51.抛出异常当程序发生异常时,产生一个异常事件,生成一个异常对象,并把它提交给运行系统,再由运行系统寻找相应的代码来处理异常。这个过程称为抛出(throw)一个异常。一个异常对象可以由Java虚拟机生成,也可以由运行的方法生成。2.捕获异常异常抛出后,运行时系统从生成对象的代码开始,沿方法的调用栈逐层回溯查找,直到包含相应处理的方法,并把异常对象交给该方法为止,这个过程称为捕获(catch)一个异常。6

3.异常处理的类层次

Java通过错误类(Error)和异常类(Exception)来处理错误和异常,而它们都是Throwable类的子类,分别用来处理两组异常。它们的层次结构如图6-1所示。74.程序对错误与异常的三种处理方式⑴

程序不能捕获和处理的错误

Error类为错误类。⑵

程序应避免而不捕获的异常

对于运行时异常类(RuntimeException),如数组越界等,无须使用try-catch-finally语句,这类异常应通过程序调试尽量避免而不是去捕获它。⑶

必须捕获的异常

有些异常在编写程序时是无法预料了,如文件没找到异常、网络通信失败异常等。因此,为了保证程序的健壮性,Java要求必须对可能出现这些异常的代码使用try-catch-finally语句,否则编译无法通过。8常见的非运行时异常非运行时异常异常描述CloneNotsupportedException当试图克隆一个没有实现Cloneable接口的对象时抛出此异常InterruptedException当线程在很长一段时间内一直处于正在等待、休眠或暂停状态,而另一个线程用Thread类中的interrupt方法中断它时抛出该异常ClassNotFoundException当程序使用Class类中的forName方法,或者ClassLoader类中的findSystemClass方法和loadClass方法试图载入某个类而没有找到时抛出此异常InstantiationException当要被实例化的类是抽象类或接口时抛出此异常IllegalAccessException当某个方法试图载入其没有权限访问的类时抛出此异常NoSuchMethodException当某个特定的方法无法找到时抛出此异常IOException表示I/0操作时可能产生的各种异常9例6.1文件没有找到异常类importjava.io.*;publicclassTry3{publicstaticvoidmain(Stringargs[])

{

FileInputStreamfis=newFileInputStream("auto.bat");

System.out.println("Icannotfoundthisfile!");

}}

105.常见的运行时异常类

下面介绍常见的异常类,它们都是RuntimeException的子类。

⑴算术异常ArithmeticException

⑵空指针异常NullPointerException

⑶类型强制转换异常ClassCastException

⑷数组负下标异常NegativeArraySizeException

⑸数组下标越界异常ArrayIndexOutOfBoundsException11运行时异常异常描述ArrayStoreException试图将错误类型的对象存储到一个对象数组时抛出此异常ArithmeticException当出现异常的运算条件时抛出此异常,如整数除以零ClassCastException当两个没有所属关系的类的实例进行类型转换时抛出此异常IllegalArgumentException当不合法的变量或不适当的参数被传递给方法时抛出此异常IndexOutOfBoundsException索引越界ArrayIndexOutOfBoundsException数组索引小于0或者超过数组的最大长度时抛出此异常StringIndexOutOfBoundsException字符串索引小于0或者超过数组的最大长度时抛出此异常NegativeArraySizeException如果试图创建一个长度为负数的数组时抛出此异常NullPointerException当对象没有实例化就试图通过该对象的变量访问它时抛出此异常SecurityException由安全管理器抛出的异常,指示存在安全侵犯UnsupportedOperationException当不支持请求的操作时,抛出该异常常见的运行时异常(这些异常,大家在编译运行程序时,会经常遇到,需要修改程序)126.2异常处理一、异常的产生以【例6.2】产生数组下标越界异常和除数为0异常为例引出异常的产生。例6.2产生数组下标越界异常和除数为0异常publicclassTry1{

publicstaticvoidmain(Stringargs[])

{

inti=0,j=0;

inta[]={5,6,7,8};

for(i=0;i<5;i++)

System.out.println("a["+i+"]="+a[i]); System.out.println(3/j);

}}13二、使用try-

catch-finally语句捕获和处理异常

在Java的异常处理机制中,提供了try-catch-finally语句来捕获和处理一个或多个异常,语法格式如下:

try

{

<语句1>

}

catch(ExceptionType1e)

{

<语句2>

}…

finally

{

<语句3>

}14

其中,<语句1>是可能产生异常的代码;<语句2>是捕获某种异常对象时进行处理的代码,ExceptionType1代表某种异常类,e为相应的对象;<语句3>是其后必须执行的代码,无论是否捕获到异常。catch语句可以有一个或多个,但至少要有一个catch语句,finally语句可以省略。try-catch-finally语句的作用是,当try语句中的代码产生异常时,根据异常的不同,由不同catch语句中的代码对异常进行捕获并处理;如果没有异常,则catch语句不执行;而无论是否捕获到异常都必须执行finally中的代码。15例6.3异常捕获和处理publicclassTry2{

publicstaticvoidmain(Stringargs[]){

inti=0;

inta[]={5,6,7,8};

for(i=0;i<5;i++){

try{

System.out.println("a["+i+"]="+a[i]);

}

catch(ArrayIndexOutOfBoundsExceptione){

System.out.println("数组下标越界异常!");

}

finally{

System.out.println("fianllyi="+i);

}

}

}}16⑴try语句try语句大括号{}中的这段代码可能会抛出一个或多个异常。也就是说,当某段代码在运行时可能产生异常的话,需要使用try语句来试图捕获这些异常。通过这个例子我们再来深入讨论try-catch-finally语句,以及使用时要注意的问题。17⑵catch语句 ExceptionDemo6.javacatch语句的参数类似于方法的声明,包括一个异常类型和一个异常对象。

catch语句可以有多个,分别处理不同类型的异常。Java运行时系统从上向下分别对每个catch语句处理的异常类型进行检测,直到找到与类型相匹配的catch语句为止。

如果程序产生的异常和所有catch的处理的异常都不匹配,则这个异常将由Java虚拟机捕获并处理,此时与不使用try-catch-finally语句是一样的,这显然也不是我们所期望的结果。因此一般在使用catch语句时,最后一个将捕获Exception这个所有异常的超类,从而保证异常由对象自身来捕获和处理。也就是,一般先安排子类,再安排父类,否则编译时编译器会提示错误。18⑶finally语句try所限定的代码中,当抛出一个异常时,其后的代码不会被执行。通过finally语句可以指定一块代码,无论try所指定的程序块中是否抛出异常,也无论catch语句的异常类型是否与所抛出的异常的类型一致,finally所指定的代码都要被执行,它提供了统一的出口。该语句是可以省略的。196.3抛出异常一、使用throw语句抛出异常

使用throw语句抛出异常,格式如下:

throw<异常对象>

其中,throw是关键字,<异常对象>是创建的异常类对象。20例6.4抛出异常publicclassTry5{

publicvoidrun(bytek){

bytey=1,i=1;

System.out.print(k+"!=");//不换行输出

for(i=1;i<=k;i++){

try{

if(y>Byte.MAX_VALUE/i)//Integer类的常量,表示最大值

thrownewException("overflow");//溢出时抛出异常

else

y=(byte)(y*i);

}

catch(Exceptione)

{21

System.out.println("exception:"+e.getMessage());

e.printStackTrace();//显示异常信息

System.exit(0);

}

}

System.out.println(y);

}

publicstaticvoidmain(Stringargs[])

{

Try5a=newTry5();

for(bytei=1;i<10;i++)

a.run(i);

}}22

⑴抛弃异常的方法在方法声明中,添加throws(抛弃)子句表示该方法将抛出异常。

带有throws子句的方法的声明格式如下:[<修饰符>]<返回值类型><方法名>([<参数列表>])[throws<异常类>]

其中,throws是关键字,<异常类>是方法要抛出的异常类,可以声明多个异常类,用逗号隔开。

注意:将throws子句与throws在语法和使用上要加以区别。⑵由调用方法处理异常

由一个方法抛弃异常后,系统将异常向上传播,由调用它的方法来处理这些异常。刚才的例题,我们也可以用抛弃异常的方法来处理,Try6.java二、抛弃异常的方法与调用方法处理异常23例6.5抛出异常的方法与调用方法处理异常publicclassTry6{

publicvoidcalc(bytek)throwsException{

//抛出异常

bytey=1,i=1;

System.out.print(k+"!=");

for(i=1;i<=k;i++){

try{

if(y>Byte.MAX_VALUE/i)

//Integer类的常量,表示最大值

thrownewException("overflow");

//溢出时抛出异常

else

y=(byte)(y*i);

}

catch(Exceptione){

System.out.println("exception:"+e.getMessage());

e.printStackTrace();

System.exit(0);

}

}24

System.out.println(y);

}

publicvoidrun(bytek){//捕获并处理异常

try{

calc(k);

}

catch(Exceptione){

System.out.println("exception:"+e.getMessage());

e.printStackTrace();

System.exit(0);

}

}

publicstaticvoidmain(Stringargs[]){

Try6a=newTry6();

for(bytei=1;i<10;i++)

a.run(i);

}}25三、由方法抛出异常交系统处理

对于程序中需要处理的异常,一般编写try-catch-finally语句捕获并处理;而对于程序中无法处理必须由系统处理的异常,可以使用throw语句在方法中抛出异常交系统处理。26

例如,我们也可以自己根据编程的需要,抛出异常,并捕获处理。publicclassDemo1{

//异常用法举例

staticinta,b,c;

publicstaticvoidmain(Stringargs[]){

try{

a=100;

b=Integer.parseInt(args[0]);

if(b==13)

throw(newArithmeticException());//方法中抛出异常

c=a/b;

System.out.println("a/b="+c);

}

catch(ArrayIndexOutOfBoundsExceptione){

System.out.println("没有命令行第一个参数");}

catch(ArithmeticExceptione){

System.out.println("算数运算错误");}

}}276.4自定义异常类

虽然Java已经预定义了很多异常类,但有的情况下,程序员不仅需要自己抛出异常,还要创建自己的异常类。这时可以通过创建Exception的子类来定义自己的异常类。28Java异常类体系中不包含所需要的异常类型。用户需要将自己所提供类的异常与其他人提供的异常进行区分。类中将多次抛出这种类型的异常。如果使用其它程序包中定义的异常类,将影响程序包的独立性与自包含性。下面给出一些原则,提示读者何时需要自己定义异常类。满足下列任何一种或多种情况就应该考虑自己定义异常类。29Throwable定义的几个常用方法方法描述ThrowablefillStackTrace()返回一个包含完整堆栈轨迹的Throwable对象,该对象可能被再次引发StringgetLocalizedMessage()返回一个异常的局部描述StringgetMessage()返回一个异常的描述voidprintStackTrace()显示堆栈轨迹voidprintStackTrace(PrintStreams)把堆栈轨迹输出到指定的输出流voidprintStackTrace(PrintWriters)把堆栈轨迹输出到指定的PrintWriterStringtoString()返回此异常的简短描述30例6.6自定义异常类 MyException.javaclassMyExceptionextendsException//自定义异常类{

MyException(){}

MyException(Stringmsg)

{

super(msg);}}classUsingMyException//抛出异常类{

Voidf()throwsMyException

{

System.out.println("ThrowsMyExceptionfromf()");

thrownewMyException();

}

Voidg()throwsMyException

{

System.out.println("ThrowsMyExceptionfromg()");

thrownewMyException("originateding()");

}}31publicclassTestMyException//捕获并处理异常{

publicstaticvoidmain(Stringargs[]){

UsingMyExceptionm=newUsingMyException();//创建自定义异常类对象

try{

m.f();

}

catch(MyExceptione){

e.printStackTrace();

}

try{

m.g();

}

catch(MyExceptione){

e.printStackTrace();

}

}}326.5项目拓展编写一个程序,对数组下标越界的异常进行捕捉和处理,操作方法如下。(1)打开“记事本”软件,键入如下的程序内容:33publicclassShuzuyichang{

publicstaticvoidmain(Stringargs[]){

int[]nums=newint[10];

for(inti=0;i<=10;i++){

try{

nums[i]=i+1;}

catch(ArrayIndexOutOfBoundsExceptione){

System.out.println("数组下标越界,产生异常:"+e);

}

finally{

if(i<10)

System.out.println("i="+i+","+"nums[i]="+nums[i]);

}

}

}}34(2)在上面的程序中,定义的数组范围是number[0]~number[9],当i循环到10的时候,数组越界,产生异常。在Exception类的所有子类中都

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论