第五章Java的异常处理.ppt

上传人:sccc 文档编号:4880301 上传时间:2023-05-21 格式:PPT 页数:70 大小:544.51KB
返回 下载 相关 举报
第五章Java的异常处理.ppt_第1页
第1页 / 共70页
第五章Java的异常处理.ppt_第2页
第2页 / 共70页
第五章Java的异常处理.ppt_第3页
第3页 / 共70页
第五章Java的异常处理.ppt_第4页
第4页 / 共70页
第五章Java的异常处理.ppt_第5页
第5页 / 共70页
点击查看更多>>
资源描述

《第五章Java的异常处理.ppt》由会员分享,可在线阅读,更多相关《第五章Java的异常处理.ppt(70页珍藏版)》请在三一办公上搜索。

1、第五章 Java的异常处理,为什么要异常处理?,对于任何语言的程序设计而言,错误的发生总是不可避免的.比如说:用户输入出错 所需文件找不到 运行时磁盘空间不够 内存耗尽无法进行类的实例化 算术运算错(数的溢出,被零除)数组下标越界 JVM崩溃 当Java程序出现以上的错误时,就会在所处的方法中产生一个异常对象。这个异常对象包括错误的类型,错误出现时程序的运行状态以及对该错误的详细描述。下面我们先看一个简单的例子。,例5.1public class ExceptionDemo public static void main(String args)int x=100;System.out.pri

2、ntln(The result is+x/10);System.out.println(Divided by zero:+x/0);,当我们对其编译后运行时,其对应的结果如下:其意思是说,本程序执行到语句“System.out.println(Divided by zero:+x/0)”时,系统会抛出一个例外,该例外在Java中定义为Arithmetic Exception(即属于算术运算例外)。,c:jbuilder3javabinjava Exception DemoThe result is10Exception in thread main java.lang.Arithmetic E

3、xception:/by zero at Exception Demo.main(Exception Demo.java:5),5.1 什么是异常,异常(Exception)又称为例外,是指在程序运行过程中发生的非正常事件,它会中断指令的正常执行,影响程序的正常运行。,异常对象,在Java语言中,我们用异常对象来表示不同的异常。所谓Java异常对象就是一个存放着相关错误信息的对象,如果方法运行时产生了异常,该方法就可以抛出一个异常对象为了表示不同种类的异常,Java语言中定义了许多异常类。,异常处理的一般步骤:异常抛出异常捕获异常处理,5.2 异常处理机制,异常处理机制,在Java程序的执行过

4、程中,如果出现了异常事件,就会生成一个异常对象。生成的异常对象将传递给Java运行时系统,这一异常的产生和提交过程称为抛出(throw)异常。,异常处理机制,当Java运行时系统得到一个异常对象时,它将会寻找处理这一异常的代码。找到能够处理这种类型的异常的方法后,运行时系统把当前异常对象交给这个方法进行处理,这一过程称为捕获(catch)异常。如果Java运行时系统找不到可以捕获异常的方法,则运行时系统将终止,相应的Java程序也将退出。,方法的调用堆栈,Java程序在执行的过程中,形成了一个先进后出的调用堆栈,各方法之间依照调用先后的不同,由先至后的进入调用堆栈,堆栈的最上层即是当前被调用执

5、行的方法。该方法执行完毕后,会将处理器控制权交还给调用他的方法,依此类推。,方法调用堆栈中异常对象的传递,当某一方法中的一个语句抛出一个异常时,如果该方法中没有处理该异常的语句,那么该方法就会中止执行,并将这个异常传递给堆栈中的下一层方法,直到某一方法中含有处理该异常的语句为止。如果该异常被传递至主方法,而主方法中仍然没有处理该异常的语句,则异常将会被抛至JVM,程序中断。,调 用,传 递,例 程,public class ExampleOfException String lines=The first line,The second line,The last line;public st

6、atic void main(String args)ExampleOfException eoe=new ExampleOfException();eoe.methodA();System.out.println(Program finished.);void methodA()methodB();void methodB()methodC();void methodC()for(int i=0;i4;i+)System.out.println(linesi);,The first lineThe second lineThe last lineException in thread mai

7、n java.lang.ArrayIndexOutOfBoundsException:3 at ExampleOfException.methodC(ExampleOfException.java:16)at ExampleOfException.methodB(ExampleOfException.java:12)at ExampleOfException.methodA(ExampleOfException.java:9)at ExampleOfException.main(ExampleOfException.java:6),Java中的异常类,在Java语言中,任何的异常对象都是Thr

8、owable类的直接子类或间接子类的实例。Java的类库已经提供了一些常见的异常类,如果这些异常类不能够满足要求,用户也可以创建自己的异常类。,异常(Throwable)分类,Error动态链接失败,虚拟机错误等,通常Java程序不应该捕获这类异常,也不会抛出这种异常。Exception运行时异常继承于RuntimeException。Java编译器允许程序不对它们做出处理。非运行时异常除了运行时异常之外的其他由Exception继承来的异常类。Java编译器要求程序必须捕获或者声明抛出这种异常。,Error类,Error类表示Java运行时产生的系统内部错误或资源耗尽等严重错误。这种错误通常

9、是程序无法控制和解决的,如果发生这种错误,通常的做法是通知用户并中止程序的执行。,典型的错误类,NoClassDefFoundErrorOutOfMemoryErrorVirtualMachineError。,表5.1 Java常见错误列表,Exception类,Exception的子类表示了不同类型的异常,例如RuntimeException表示运行时异常,而IOException表示I/O问题引起的异常。这些子类也可以被继承以对不同类型的异常进行细分,如RuntimeException还可细分为NullPointerException、ArithmeticException等;IOExce

10、ption还可细分为FileNotFoundException、EOFException等。,典型的异常类,ArithmeticExceptionArrayIndexOutOfBandsExceptionIOExceptionFileNotFoundExceptionNullPointerExceptionNumberFormatException,表5.2 Java常见的一般异常列表,表5.3 Java常见的运行异常列表,必检异常与非必检异常,RuntimeException类及其子类被称为“运行时异常”一般发生在JRE内部也称“非必检异常”如NullPointerException其他异常

11、被成为“非运行时异常”一般发生在JRE外部也称“必检异常”如IOException,5.3 异常类的使用,要捕获一个异常,程序员只需要在程序中设置一个try/catch块,其格式如下:try 抛出异常的代码 catch(某Exception类型 e)处理该异常类型的代码 catch(某Exception类型 e)处理该异常类型的代码,try捕获异常的第一步是用try选定捕获异常的范围,由try所限定的代码块中的语句在执行过程中可能会生成异常对象并抛出。,catch 每个try代码块可以伴随一个或多个catch语句,用于处理try代码块中所生成的异常事件。catch语句只需要一个形式参数指明它所

12、能够捕获的异常类型,这个类必须是Throwable的子类,运行时系统通过参数值把被抛出的异常对象传递给catch块.在catch块中是对异常对象进行处理的代码,与访问其它对象一样,可以访问一个异常对象的变量或调用它的方法。getMessage()是类Throwable所提供的方法,用来得到有关异常事件的信息,类Throwable还提供了方法printStackTrace()用来跟踪异常事件发生时执行堆栈的内容。,异常的捕获过程,当try块中的某条代码抛出异常时:首先,自该语句的下一条语句起的所有try块中的剩余语句将被跳过不予执行;其次,程序执行catch子句进行异常捕获,异常捕获的目的是进行

13、异常类型的匹配,并执行与所抛出的异常类型相对应的catch子句中的异常处理代码。,异常的捕获过程,需要注意的是:如果try块中没有任何的异常抛出,则所有的catch子句将会被跳过;如果try块中所抛出的异常对象类型与所有的catch子句中的所声明的异常类型都不匹配,则方法会立即中止,并将该异常对象继续抛出,沿调用堆栈传递。,example,public class ExampleOfException String lines=The first line,The second line,The last line;public static void main(String args)Exa

14、mpleOfException eoe=new ExampleOfException();eoe.methodA();System.out.println(Program finished.);.void methodC()for(int i=0;i4;i+)try System.out.println(linesi);catch(ArrayIndexOutOfBoundsException e)System.out.println(Re-setting Index Value);,example,上面的例子中可能会产生数组越界异常,所以将其置于try块中,并在catch子句中对ArrayIn

15、dexOutOfBoundsException类型的异常进行捕获,并进行处理。如果try块中可能抛出多个类型的异常,程序员可以使用多个catch子句对这些异常进行捕获,每种异常类型对应一个单独的catch子句。需要注意的是,这些catch子句是顺序执行的。这意味着,异常对象总是被第一个catch子句首先捕获,如果类型不匹配,才会执行下一个catch子句。读者可以试着分析下面的程序片断,看看有什么样的问题存在。,问题,Java运行系统从上到下分别对每个catch语句处理的例外类型进行检测,直到类型匹配为止;catch语句的排列顺序应该是从子类到父类,try catch(Exception e)c

16、atch(IOException e)catch(ArrayIndexOutOfBoundsException e),catch语句的顺序,捕获异常的顺序和不同catch语句的顺序有关,当捕获到一个异常时,剩下的catch语句就不再进行匹配。因此,在安排catch语句的顺序时,首先应该捕获最特殊的异常,然后再逐渐一般化。也就是一般先安排子类,再安排父类。,finally捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,finally块中的语句都会被执行。,finall

17、y,finally子句的一般格式:,try 抛出异常的代码 catch(某Exception类型 e)处理该异常类型的代码 catch(某Exception类型 e)处理该异常类型的代码 finally 最后一定会被执行的代码,finally,不论try块中的代码是否抛出异常及异常是否被捕获,finally子句中的代码一定会被执行:如果try块中没有抛出任何异常,当try块中的代码执行结束后,finally中的代码将会被执行;如果try块中抛出了一个异常且该异常被catch正常捕获,那么try块中自抛出异常的代码之后的所有代码将会被跳过,程序接着执行与抛出异常类型匹配的catch子句中的代码,

18、最后执行finally子句中的代码。如果try块中抛出了一个不能被任何catch子句捕获(匹配)的异常,try块中剩下的代码将会被跳过,程序接着执行finally子句中的代码,未被捕获的异常对象继续抛出,沿调用堆栈顺序传递。,问题,当调用上述方法m()时,try块中包含方法的return语句,返回值为1。然而,实际调用该方法后产生的返回值为0。这是因为在方法实际返回并结束前,finally子句中的内容无论如何要被执行,所以finally子句中的return语句使得该方法最终实际返回值为0。,public int m()try return 1;finallyreturn 0;,example,

19、public class TryCatchFinally static void Proc(int sel)System.out.println(-In Situation+sel+-);try if(sel=0)System.out.println(no Exception caught);return;else if(sel=1)int i=0;int j=4/i;else if(sel=2)int iArray=new int4;iArray10=3;,example,catch(ArithmeticException e)System.out.println(Catch+e);catc

20、h(ArrayIndexOutOfBoundsException e)System.out.println(Catch+e.getMessage();catch(Exception e)System.out.println(Will not be executed);finally System.out.println(in Proc finally);public static void main(String args)Proc(0);Proc(1);Proc(2);,程序运行结果:-In Situation0-no Exception caughtin Proc finally-In S

21、ituation1-Catch java.lang.ArithmeticException:/by zeroin Proc finally-In Situation2-Catch 10in Proc finally,声明异常,一个方法不处理它产生的异常,而是沿着调用堆栈向上传递,由调用它的方法来处理这些异常,则需要声明异常。相比较捕获异常来讲,这种处理异常的方式较消极,所以有时候也该方式叫做异常的消极处理方式,管捕获异常叫做积极处理方式。,声明抛出异常,声明抛出异常是在一个方法声明中的throws子句中指明的。声明异常的方法:returnType methodName(paramlist)th

22、rows exceptionList例如:void compute(int x)throws ArithmeticException 例如:public int read()throws IOException.throws子句中同时可以指明多个异常,说明该方法将不对这些异常进行处理,而是声明抛出它们。,public class ThrowsException static void proc(int sel)throws ArithmeticException,ArrayIndexOutOfBoundsExceptionSystem.out.println(In Situation+sel)

23、;if(sel=0)System.out.println(no Exception caught);return;else if(sel=1)int iArray=new int4;iArray10=3;,public static void main(String args)tryproc(0);proc(1);catch(ArrayIndexOutOfBoundsException e)System.out.println(Catch+e);finallySystem.out.println(in Proc finally);,运行结果,In Situation0no Exception

24、caughtIn Situation1Catch java.lang.ArrayIndexOutOfBoundsException:10in Proc finally,example,public class ThrowsException1 static void Proc(int sel)throws ArrayIndexOutOfBoundsException System.out.println(-In Situation+sel+-);if(sel=0)System.out.println(no Exception caught);return;else if(sel=1)int i

25、Array=new int4;iArray10=3;,example,public static void main(String args)try Proc(0);Proc(1);catch(ArrayIndexOutOfBoundsException e)System.out.println(Catch+e);finally System.out.println(in Proc finally);,程序运行结果:-In Situation0-no Exception caught-In Situation1-Catch java.lang.ArrayIndexOutOfBoundsExce

26、ption:10in Proc finally,抛出异常,若某方法中需要直接抛出某异常时,可使用throw语句实现,具体步骤应该是:选择合适的异常类;创建该类的一个对象;使用throw语句抛出该对象。,抛出异常,抛出异常首先要生成异常对象,异常或者由虚拟机生成,或者由某些类的实例生成,也可以在程序中生成。生成异常对象是通过throw语句实现的。IOException e=new IOException();throw e;可以抛出的异常必须是Throwable或其子类的实例。下面的语句在编译时将会产生语法错误:throw new String(want to throw);,抛出异常,例如,某

27、方法readFile()对文件进行读操作,根据前面章节的介绍可以知道:当进行I/O操作时,可能会产生I/O异常。所以,在方法readFile中如果读文件操作不成功,则应抛出I/O异常。如下列程序片断所示:,readFile()throws IOException if(读文件不成功)throw new IOExcepion();,抛出异常,如果一个方法可能抛出多个必检异常,那么必须在方法的声明部分一一列出,多个异常间使用逗号进行分隔:,Class MyClass public myMethod(String s)throws IOException,MalformedURLException,

28、抛出异常,一个方法必须通过throws语句在方法的声明部分说明它可能抛出而并未捕获的所有的“必检异常”,如果没有这么做,将不能通过编译。值得注意的是:如果在子类中覆盖了父类的某一方法,那么该子类方法不可以比被其覆盖的父类方法抛出更多的异常(但可以更少)。所以,如果被覆盖父类的方法没有抛出任何的“必检异常”,那么子类方法绝不可能抛出“必检异常”。,抛出异常,在下面的例子里,对于父类SuperClass而言,类SubClassA是正确的子类,而SubClassB则是错误的。,class SuperClasspublic superMethod()throws EOFException class

29、SubClassA extends SuperClass/正确public superMethod()class SubClassB extends SuperClass/错误public superMethod()throws FileNotFoundException,5.4 自定义异常类,Java语言中允许用户定义自己的异常类,但自定义异常类必须是Throwable的直接子类或间接子类。同时要理解一个方法所声明抛出的异常是作为这个方法与外界交互的一部分而存在的。方法的调用者必须了解这些异常,并确定如何正确的处理他们。,创建异常类注意:,根据Java异常类的继承关系,用户最好将自己的异常类

30、定义为Exception的子类,而不要将其定义为RuntimeException的子类。因为对于RuntimeException的子类而言,即使调用者不进行处理,编译程序也不会报错。将自定义异常类定义为Exception的子类,可以确保调用者对其进行处理。,example,class MyException extends Exception private int detail;MyException(int a)detail=a;public String toString()return MyException+detail;,example,public class Exception

31、Demo static void compute(int a)throws MyException System.out.println(called compute(+a+);if(a10)throw new MyException(a);System.out.println(normal exit);public static void main(String args)try compute(1);compute(20);catch(MyException e)System.out.println(Caught+e);,程序运行结果:called compute(1)normal exi

32、tcalled compute(20)Caught MyException 20,异常类的使用,运行时异常则表示由运行时系统所检测到的程序设计问题或者API的使用不当问题,它可能在程序的任何地方出现:(1)对于运行时异常,如果不能预测它何时发生,程序可以不做处理,而是让Java虚拟机去处理它。(2)如果程序可以预知运行时异常可能发生的地点和时间,则应该在程序中进行处理,而不应简单的把它交给运行时系统。,异常类的使用,(3)在自定义异常类时,如果它所对应的异常事件通常总是在运行时产生的,而且不容易预测它将在何时、何处发生,则可以把它定义为运行时异常,否则应定义为非运行时异常。,异常类的使用,积极

33、处理方式:import java.io.*;class ExceptionDemo1public static void main(String args)try FileInputStream fis=new FileInputStream(text);catch(FileNotFoundException e),异常类的使用,消极处理方式:import java.io.*;class ExceptionDemo1public static void main(String args)throws FileNotFoundException FileInputStream fis=new F

34、ileInputStream(text);,异常类的使用,如果采用消极处理方式,则由调用该方法的方法进行处理;但是调用该方法的方法也可以采用消极和积极两种处理方式,一直传递到Java运行环境.,异常的优点,将错误处理代码与“常规”代码分离;将错误沿调用堆栈传递;可以由感兴趣的方法来处理异常对错误类型进行分组和区分。,说明的问题,方法也可以不对异常进行捕获而直接将其抛出,并在方法声明中进行说明,那么对方法产生的异常到底是应该直接进行捕获还是应该将其进行传递呢?一般来说,对于方法的最终调用者而言,他必须捕获并处理该方法抛出的异常。而对于抛出异常的方法而言,应该对方法可能产生的异常进行区分,尽量避免

35、一些异常的产生,捕获并处理那些你知道如何处理的异常,而对那些你不知道方法的调用者会如何处理的异常,最好将它们留给方法的调用者进行处理,这样会增加程序的灵活性。,说明的问题,需要特别指出的是,虽然异常处理机制为程序员提供了非常大的方便,但是作为一个好的程序员要尽量避免异常的过度使用。这是因为:异常对象的实例化和其后续处理工作是非常消耗资源的,过度的使用异常会明显影响程序的执行速度。所以,在使用异常处理时应该仔细考虑,只对有必要的异常情况使用异常,而不可以将异常泛化。,两段代码的比较,代码1:try int n=InputReader.inputInteger(请输入一个整数);if(n1)thr

36、ow new NumberFormatException();catch(NumberFormatException e)System.out.println(输入范围错误!);代码2:int n=InputReader.inputInteger(请输入一个整数);if(n1)System.out.println(输入范围错误!);,代码1采用了异常处理方式;代码2则通过对用户输入的分析避免了异常的使用,提高了代码效率。,问题,下面的代码合法吗?try.finally.,下面的代码可以捕获何种异常?使用这种异常处理器有什么问题?catch(Exception e).,问题,下面的处理器可以捕获

37、什么异常?catch(Exception e).catch(ArithmeticException a).这个异常处理器中有错误吗?此代码能否被编译?,问题,public static void cat(File named)RandomAccessFile input=null;String line=null;try input=new RandomAccessFile(named,“r”);while(line=input.readLine()!=null System.out.println(line);return;finally if(input!=null)input.close();,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 建筑/施工/环境 > 农业报告


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号