《JAVA语言与编程第6章异常处理.ppt》由会员分享,可在线阅读,更多相关《JAVA语言与编程第6章异常处理.ppt(20页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第6章 异常处理6.1 异常和异常类异常和异常类 异常异常(exception)又称例外又称例外,是特殊的运行错误对象是特殊的运行错误对象.Java中定义了很多异常类中定义了很多异常类,每个异常类代表了一种运行错每个异常类代表了一种运行错误误,类中包含了该运行错误的信息和处理错误的方法等内容类中包含了该运行错误的信息和处理错误的方法等内容.每当每当Java程序运行过程中发生一个可识别的运行错误时程序运行过程中发生一个可识别的运行错误时,即即该错误有一个异常类与之相对应时该错误有一个异常类与之相对应时,系统都会产生一个相应系统都会产生一个相应的异常类的对象的异常类的对象,即产生一个异常即产生一个
2、异常.一旦一个异常对象产生了一旦一个异常对象产生了,系统中就有相应的机制来处理它系统中就有相应的机制来处理它,确保不会产生死机确保不会产生死机,死循环死循环或其他对或其他对os的损害的损害,从而保证了整个程序运行的安全性从而保证了整个程序运行的安全性.6.1 异常和异常类异常和异常类(续续)6.1.1 异常类结构与组成异常类结构与组成 Java的所有异常类都是系统类的所有异常类都是系统类Throwable的子类的子类,Java中主要异常类中主要异常类层次结构如下图层次结构如下图:Throwable类是类是java.lang包中的一个类包中的一个类,它直接派生了两个子类它直接派生了两个子类:Er
3、ror类和类和Exception类类.Error是与系统或是与系统或JVM相关的异常相关的异常,标志着严重的系统标志着严重的系统错误错误,是不可恢复的是不可恢复的;Exception用于用户程序可能捕获的异常用于用户程序可能捕获的异常,该类及其该类及其子类是一些与用户程序相关的异常子类是一些与用户程序相关的异常,它们也可以用作创建自定义异常类的它们也可以用作创建自定义异常类的超类超类.Exception的一个重要子类的一个重要子类RuntimeException,运行时异常运行时异常,该类型该类型的异常自动为程序定义的异常自动为程序定义,包括被零除异常和数组下标越界异常等包括被零除异常和数组下
4、标越界异常等.6.1 异常和异常类异常和异常类(续续)1.Exception类的构造函数类的构造函数 public Exception();public Exception(String s);其中第二个构造函数可以接收字符串参数传入的信息其中第二个构造函数可以接收字符串参数传入的信息,该信息通常是对该信息通常是对异常的描述异常的描述.2.Exception类及其子类从类及其子类从Throwable类继承的几个重要的方法类继承的几个重要的方法:lpublic String getMessage()该方法返回一个详细描述异常的字符串该方法返回一个详细描述异常的字符串lpublic void pr
5、intStackTrace()该方法没有返回值该方法没有返回值,它的功能是输出它的功能是输出当前异常对象的堆栈使用轨迹当前异常对象的堆栈使用轨迹,即程序先后调用执行了哪些对象或类即程序先后调用执行了哪些对象或类的哪些方法的哪些方法,导致运行过程中产生了这个异常对象导致运行过程中产生了这个异常对象.lpublic String toString()该方法返回一个简洁描述该异常的字符串该方法返回一个简洁描述该异常的字符串6.1.2 非检查型异常与检查型异常非检查型异常与检查型异常 根据编译器是否对异常做检查根据编译器是否对异常做检查,Java的异常分为两类的异常分为两类:非检查型异常和非检查型异常
6、和检查型异常检查型异常.在异常的层次结构中在异常的层次结构中,Error及其子类和及其子类和RuntimeException及其子类都是非检查型异常及其子类都是非检查型异常,它是一种编译器不检查一个方法是否处理或它是一种编译器不检查一个方法是否处理或指定向上抛出的异常指定向上抛出的异常,它们都是它们都是Java运行时系统内发生的异常运行时系统内发生的异常.6.1 异常和异常类异常和异常类(续续)常见的非检查型异常常见的非检查型异常:异异 常常异常对应的运行错误异常对应的运行错误ArithmeticException算算术错误术错误,例如被,例如被0 0除除ArrayIndexOutOfBoun
7、dsException数数组组下下标标越界越界ClassCastException无效的无效的类类型型转换转换IndexOutOfBoundsException某些某些类类型的下型的下标标越界越界EmptyStackException空空栈栈异常异常NegativeArraySizeException用用负负数数创创建数建数组组NullPointerException使用空引用使用空引用错误错误NumberFormatException字符串到数字格式的无效字符串到数字格式的无效转换转换StringIndexOutOfBounds尝试尝试在一个字符串在一个字符串边边界之外界之外进进行索引行索引
8、6.1 异常和异常类异常和异常类(续续)Exception及其除了及其除了RuntimeException以外的所有子类都是检查型以外的所有子类都是检查型异常异常,它是一种编译器必须检查一个方法是否处理或指定向上抛出的异常它是一种编译器必须检查一个方法是否处理或指定向上抛出的异常,是在是在Java运行时系统外的代码中发生的异常运行时系统外的代码中发生的异常,如果一个方法没有处理或如果一个方法没有处理或指定向上抛出可能发生的检查型异常指定向上抛出可能发生的检查型异常,那么该方法就不能通过编译器的编那么该方法就不能通过编译器的编译译.常见的检查型异常如下常见的检查型异常如下:这里只讨论与用户应用程
9、序相关的异常这里只讨论与用户应用程序相关的异常,即即Exception分支分支,它包括所有它包括所有的检查型异常和运行时异常的检查型异常和运行时异常.异异 常常异常对应的运行错误异常对应的运行错误ClassNotFoundException未找到欲装未找到欲装载载的的类类CloneNotSupportedException尝试尝试复制一个没有复制一个没有实现实现Cloneable接口的接口的对对象象FileNotFoundException未找到指定的文件或目未找到指定的文件或目录录IllegalAccessException对对一个一个类类的的访问访问被拒被拒绝绝IOException输输入
10、、入、输输出出错误错误InterruptedException线线程在睡眠、等待或因其他原因程在睡眠、等待或因其他原因暂暂停停时时被其他被其他线线程打断程打断6.2 异常的捕获和处理异常的捕获和处理 Java的异常处理机制可以概括为以下几个过程的异常处理机制可以概括为以下几个过程:(1)在在Java程序的执行过程中程序的执行过程中,如果出现了一个可识别的错误如果出现了一个可识别的错误,则会生成一个与该错误相对应的异常类的对象则会生成一个与该错误相对应的异常类的对象,该异常将该异常将被提交给被提交给Java运行时系统运行时系统,这个过程称为抛出异常这个过程称为抛出异常(2)当当Java运行时系统
11、接收到异常对象后运行时系统接收到异常对象后,会寻找能处理这一会寻找能处理这一异常的代码并把当前异常对象交给其处理异常的代码并把当前异常对象交给其处理,这一过程成为这一过程成为捕获异常捕获异常(3)如果如果Java运行时系统找不到处理异常的程序运行时系统找不到处理异常的程序,那么它将终那么它将终止程序的执行止程序的执行,最后调用默认异常处理程序来处理异常最后调用默认异常处理程序来处理异常6.2 异常的捕获和处理异常的捕获和处理(续续)Java语言提供语言提供try-catch-finally语句来捕获并处理一个或多个异常语句来捕获并处理一个或多个异常,其其一般格式为一般格式为:try catch
12、()catch()catch()finally 6.2 异常的捕获和处理异常的捕获和处理(续续)关于异常处理结构的几点说明关于异常处理结构的几点说明:(1)try语句中是一段可能产生异常的代码段语句中是一段可能产生异常的代码段,可能抛出一个或多个异常可能抛出一个或多个异常,try指定了指定了catch捕获异常的代码范围捕获异常的代码范围(2)catch语句语句:1try后通常跟一个或多个后通常跟一个或多个catch语句来处理语句来处理try中异常中异常,若若try中没有产中没有产 生异常生异常,则则catch块不会执行块不会执行 2catch语句需要一个形式参数语句需要一个形式参数:异常类名及
13、其对象异常类名及其对象,运行时由系统通运行时由系统通过过 参数值把抛出的异常对象传递给参数值把抛出的异常对象传递给catch语句块语句块,在语句块中对异常做在语句块中对异常做 相应的处理相应的处理 3处理异常时处理异常时,通过异常类提供的通过异常类提供的toString()或或getMessage()方法可以方法可以 获得有关异常的信息获得有关异常的信息,最常用的是最常用的是printStackTrace()4出现异常时出现异常时,系统根据系统根据catch语句的出现顺序对异常类型进行检测语句的出现顺序对异常类型进行检测,因因 此此catch语句块的排列顺序应该从特殊到一般语句块的排列顺序应该
14、从特殊到一般(3)finally语句语句:为程序提供一个统一的出口为程序提供一个统一的出口,通常在该语句块中可以进通常在该语句块中可以进行资源的清除行资源的清除,如关闭文件等如关闭文件等.6.2 异常的捕获和处理异常的捕获和处理(续续)public class ExceptionFlow public static void main(String args)System.out.println(显示显示Java异常处理的执行流程异常处理的执行流程);System.out.println(即将进入即将进入try块块);try System.out.println(进入了进入了try块!块!);
15、int b=0;int a=3;if(b=0)System.out.println(异常发生!异常发生!);a=a/b;System.out.println(没有异常发生!没有异常发生!);catch(ArithmeticException e)System.out.println(进入进入catch块,处理异常块,处理异常!);System.out.println(catch块之后!块之后!);6.2 异常的捕获和处理异常的捕获和处理(续续)例例:不含不含catch子句的异常处理子句的异常处理npublic class ExceptionNonCatchn public static voi
16、d main(String strs)n System.out.println(RuntimeException non-catch clause test.);n int a=5;n int b=0;n for(int i=1;i=0;i-)n tryn System.out.println(-i=+i+-);n b=a/i;n System.out.println(After no exception occur!);n n finally System.out.println(Finally block!);n System.out.println(After finally block
17、!);n n n6.2 异常的捕获和处理异常的捕获和处理(续续)例例:捕获被零除异常捕获被零除异常npublic class ExceptionWithCatchn public static void main(String strs)n System.out.println(RuntimeException with catch clause test.);n int a=5;n int b=0;n for(int i=1;i=0;i-)n tryn System.out.println(-i=+i+-);n b=a/i;n System.out.println(After no exce
18、ption occur!);n n catch(ArithmeticException e)n System.out.println(Catch block,i.e.exception handling code.);n n finally System.out.println(Finally block!);n System.out.println(After finally block!);n n n6.2 异常的捕获和处理异常的捕获和处理(续续)从以上两个例子从以上两个例子,可以总结出以下几点可以总结出以下几点:l不论异常是否发生不论异常是否发生,finally块总是被执行块总是被执行.
19、当一个当一个异常在本层没有相应的异常在本层没有相应的catch处理块时处理块时,执行完执行完finally块后块后,再将这个异常抛出给上层再将这个异常抛出给上层ltry语句块中异常发生点以后的代码不能被执行语句块中异常发生点以后的代码不能被执行l当没有当没有catch块处理相应的异常时块处理相应的异常时,默认异常处理默认异常处理程序打印出有关的异常信息并终止程序程序打印出有关的异常信息并终止程序6.3 指定方法抛出异常指定方法抛出异常 在有些情况下在有些情况下,方法暂时还不能确定如何处理异常方法暂时还不能确定如何处理异常,它可以将异常进一它可以将异常进一步向上层抛出步向上层抛出,将处理异常的任
20、务留给调用它的方法将处理异常的任务留给调用它的方法.如果是检查型异常如果是检查型异常,抛出异常的方法必须在方法头使用抛出异常的方法必须在方法头使用throws子句指定向上抛出的异常子句指定向上抛出的异常,如如果是非检查型异常果是非检查型异常,可以不这么做可以不这么做,但是为了给调用者一个明确的接口但是为了给调用者一个明确的接口,建建议也这么做议也这么做.指定方法抛出异常的格式为指定方法抛出异常的格式为:()throws 例例:下面的方法头使用了下面的方法头使用了throws子句子句public void readFile(String file)throws FileNotFoundExcep
21、tion FileInputStream f=new FileInputStream(file);/可能产生可能产生FileNotFoundException异常异常/例例:ThrowsException.java6.3 指定方法抛出异常指定方法抛出异常(续续)注注:(1)若程序执行时一个检查型异常被抛出若程序执行时一个检查型异常被抛出,那么要么在当前方那么要么在当前方法中捕获并抛出法中捕获并抛出,否则必须在方法声明中用否则必须在方法声明中用throws子句列子句列出所抛出的异常出所抛出的异常,否则编译无法通过否则编译无法通过(2)如果是运行时异常可以不捕获它如果是运行时异常可以不捕获它,也可
22、以不在方法头部声也可以不在方法头部声明异常明异常.但如果运行时异常要进一步向上抛出的话但如果运行时异常要进一步向上抛出的话,建议最建议最好也在好也在throws子句中列出子句中列出,这样便于方法调用者处理异常这样便于方法调用者处理异常;否则否则,如果调用方法中没有给出异常处理程序如果调用方法中没有给出异常处理程序,则系统沿则系统沿着调用堆栈继续向上查找着调用堆栈继续向上查找,当找不到匹配的处理程序时当找不到匹配的处理程序时,在在默认情况下系统将终止程序的执行默认情况下系统将终止程序的执行.6.4 抛出异常抛出异常 抛出异常有两种方法抛出异常有两种方法,一种是系统自动抛出异常一种是系统自动抛出异
23、常,另外一种是用另外一种是用throws语句指定在程序中抛出异常语句指定在程序中抛出异常.6.4.1 系统自动抛出的异常系统自动抛出的异常 所有的系统异常都可以由系统自动抛出所有的系统异常都可以由系统自动抛出,但用户自定义的异常不能由系但用户自定义的异常不能由系统自动抛出统自动抛出.例例:系统自动抛出异常系统自动抛出异常ArrayIndexOutOfBoundsExceptionpublic class TestThrowSystemException public static void main(String args)int a=1,2,3;int i=3;System.out.prin
24、tln(ai);/数组下标越界,引发系统抛出异常数组下标越界,引发系统抛出异常 Exception in thread main java.lang.ArrayIndexOutOfBoundsException:3 at TestThrowSystemException.main(TestThrowSystemException.java:5)6.4 抛出异常抛出异常(续续)6.4.2 throws语句抛出的异常语句抛出的异常 在在Java中可以使用中可以使用throw语句指定在程序中抛出某种类型的异常语句指定在程序中抛出某种类型的异常:throw ;注注:如果程序企图抛出一个不是如果程序企图
25、抛出一个不是throwable或其子类的对象或其子类的对象,程序将无法程序将无法通过编译通过编译.而在一般情况下而在一般情况下,程序中抛出的应该是程序中抛出的应该是Exception或其子类或其子类的对象的对象.例例:public class TestThrow public static void main(String args)throws ArrayIndexOutOfBoundsException int a=1,2,3;int i=3;if (i2|i0)throw new ArrayIndexOutOfBoundsException();else System.out.print
26、ln(ai);6.4 抛出异常抛出异常(续续)使用使用throw语句抛出异常应注意的几个问题语句抛出异常应注意的几个问题:(1)一般这种抛出异常的语句应该被定义为在满足一定条件时执行一般这种抛出异常的语句应该被定义为在满足一定条件时执行,例如例如把把throw语句放在语句放在if分支中分支中.(2)catch后的参数类型后的参数类型(T1)必须和必须和throw后的表达式类型后的表达式类型(T2)一致一致,即或即或者者T1和和T2一样一样,或者或者T1是是T2的父类的父类(3)含有含有throw语句的方法语句的方法,应该在方法头中抛出异常应该在方法头中抛出异常,这样做主要是为了这样做主要是为了
27、通知所有想要调用此方法的方法准备接收和处理在运行过程中可能会通知所有想要调用此方法的方法准备接收和处理在运行过程中可能会抛出的异常抛出的异常例例:ThrowExceptionDemo1.java6.4.3 自定义异常类自定义异常类 系统定义的异常用来处理系统可以识别的较常见的运行错误,对于某系统定义的异常用来处理系统可以识别的较常见的运行错误,对于某个应用程序特有的运行错误,则需要编程人员根据程序的特殊逻辑在用个应用程序特有的运行错误,则需要编程人员根据程序的特殊逻辑在用户程序中自己创建用户自定义的异常类和异常对象。户程序中自己创建用户自定义的异常类和异常对象。Java允许用户自定义异常类,但
28、必须继承现有的异常类。因此第一个自定义允许用户自定义异常类,但必须继承现有的异常类。因此第一个自定义异常类必须从系统异常类如异常类必须从系统异常类如Exception,RuntimeException或它们的子类派或它们的子类派生,其后定义的异常类可以从系统或自定义的异常类派生。生,其后定义的异常类可以从系统或自定义的异常类派生。6.4 抛出异常抛出异常(续续)class Queue private int front=0,rear=0,c=0;/队首位置队首位置,队尾位置队尾位置,队列中元素个数队列中元素个数 private int array,len;/数组及数组长度数组及数组长度 pub
29、lic Queue(int s)array=new intlen=s;public boolean isEmpty()return c=0;public int out()/出队出队 if(!isEmpty()c-;int result=arrayfront;front=(front+1)%len;return result;else return 1;/假设队列空返回假设队列空返回1 6.4 抛出异常抛出异常(续续)class EmptyQueueException extends Exception/自定义异常类自定义异常类 public EmptyQueueException(String msg)super(msg);public String getMessage()/覆盖父类的方法覆盖父类的方法 return 队列已空队列已空,执行出队操作引发异常执行出队操作引发异常;public int out()throws EmptyQueueException if(!isEmpty()c-;int result=arrayfront;front=(front+1)%len;return result;else throw new EmptyQueueException(队列已空队列已空);
限制150内