Download presentation
Presentation is loading. Please wait.
1
Java语言程序设计 第五部分 Java异常处理
2
Java异常处理 第一讲 异常处理概述
3
异常及其分类 软件的容错性 软件系统不仅自身不能有错误,还要具备较强的抗干扰能力。即使在用户操作出现错误,或遇到不可 抗拒的干扰时,软件系统也不能崩溃,而必须尽最大努力排除错误继续运行。只有这样的软件系统才会具有旺盛的生命力和广泛的应用空间。 异常 任何计算机语言的程序都难免有漏洞,捕获错误最理想的是在编译期间,然而,在实际的程序设计中,并非所有错误都能在编译期间侦测到。例如,下列情况在编译时通常检测不到:类文件丢失、想打开的文件不存在、网络连接中断、操作数超出预定范围等。这些在程序执行中,中断正常程序流程的异常条件称为错误或异常。
4
异常及其分类 错误(error) 异常( exception)
指程序运行时遇到的硬件或操作系统的错误,如内存溢出、虚拟机错误等。 错误对于程序而言是致命性的,错误将导致程序无法运行,而且程序本身不能处理错 只能依靠外界干预,否则会一直处于非正常状态。 异常( exception) 指在硬件和操作系统正常时,程序遇到的运行错,如整数进行除法运 算时除数为0,或操作数超出数据范围,或打开一个文件时发现文件不存在,或网络连接中断等。 异常对于程序而言是非致命性的,虽然异常会导致程序非正常终止,但Java的异常处理 机制使程序自身能够捕获和处理异常,由异常处理代码调整程序运行方向,使程序仍可继续运行。
5
异常处理机制 错误,程序不能处理 运行时异常,程序应避免而不捕获 其它异常,必须捕获
内存溢出、核溢出等错误,由系统进行处理, Java程序本身不能对错误进行处理。 运行时异常,程序应避免而不捕获 对于程序能够预见的异常,如除数为0、数组下标越界等,程序应该考虑周到进行事先 处理,尽量避免发生异常。例如,进行除法运算时,判断除数是否为0并给出解决办法,避免发生除数为0异常。 其它异常,必须捕获 由特殊环境错误造成的异常,如文件没找到、网络通信失败等, 必须进行捕获和处理,从而保证程序正常运行,保证程序的可靠性和安全性。
6
异常示例 public class HelloWorld{ public static void main(String args[]){
int i=0; String greeting []={ "Hello world !", "No,I mean it !", "HELLO WORD !!" }; while(i<4){ System.out.println(greeting[i]); i++; }
7
异常类的层次结构 Throwable Error Exception Object AWTException
RuntimeException IOException ……
8
Java中的常用异常类 RuntimeException ArithmeticException:一个不寻常算术运算产生的异常。
ArrayIndexOutOfBoundsException:数组索引超出范围所产生的异常。 ClassCastExcption:类对象强迫转换造成不当类对象所产生的异常。 NumberFormatException:字符串转换数值所产生的异常。 IndexOutOfBoundsException:索引超出范围所产生的异常。 NegativeException:数组建立负值索引所产生的异常。 NullPointerException:对象引用参考值为null所产生的异常。
9
Java中的常用异常类 检查异常 也称为非运行时异常。Java编译器要求程序必须处理这种异常。
ClassNotFoundException:找不到类或接口所产生的异常。 IllegaAccessException:类定义不明确所产生的异常。 InterruptedException:目前线程等待执行,另一线程中断目前线程所产生的异常。 IOException:输入输出访问异常。
10
Java异常处理 第二讲 异常处理
11
Java异常的处理方法 为了写出健壮的Java程序,当程序出现异常时就应当进行处理,Java程序对异常处理有两种方式:
通过try{}catch(){}finally{}块处理异常。 把可能会发生异常的程序代码放在try区块中,那么当程序执行发生异常时,catch区块会捕捉这个异常,并且以区块内的程序代码来处理异常,而finally区块则负责处理一些必要的工作。 将异常抛给上一层调用它的方法,由上一层方法进行异常处理或继续向更上一层方法抛出该异常。
12
try/catch 异常处理的核心是try和catch。这两个关键字要一起使用,只有try而没有catch,或者只有catch而没有try 都是不可以的。下面是try/catch异常处理代码块的基本形式: try { 可能发生异常的代码块; } catch(异常类型 异常对象名)//捕获并处理异常 异常处理代码块;
13
try/catch try块 若一个方法产生了异常,该方法就会在异常产生过程中退出。可在那个方法内部设置一个特殊的代码块,用它捕获异常。 catch 生成的异常必须在某个地方中止。这个地方就是异常控制模块。而且针对想捕获的每种异常类型,都必须有一个相应的异常控制模块。异常控制模块紧接在try块后面,且用catch(捕获)关键字标记。如下所示: try { // Code that might generate exceptions } catch(Type1 id1) { // Handle exceptions of Type1 } catch(Type2 id2) { // Handle exceptions of Type2 } catch(Type3 id3) { // Handle exceptions of Type3 }
14
try/catch 异常处理过程 捕获所有的异常
当try描述的代码段遇到异常发生时,会抛出一个异常对象,该异常由相应的catch语句捕获并处理。与一个try相关的catch语句可以有多个,构成多重catch 语句,异常类型决定了要执行哪个catch语句。也就是说,如果由一个catch语句指定的异常类型与发生的异常类型相符,那么就会执行这个catch语句(其他的catch语句则被跳过)。如果catch语句执行完毕或者没有抛出异常,就会执行最后一个catch后面的第一个语句。 捕获所有的异常 catch(Exception e) { … …} 这段代码能捕获任何异常,所以在实际使用时将其置于控制模块列表的末尾。
15
public class Exam6_2{ public static void main(String [ ] args){ try{ device(Integer.parseInt(args[0])); }catch (ArithmeticException e){ System.out.println ("输入为零,产生异常,被catch捕获到"); } System.out.println ("输入不为零,没有产生异常!"); static int device(int i){ return 10/i;
16
try/catch finally关键字的使用
有时需要在catch处理异常后进行一些其他的操作,比如关闭一个已经打开了的文件,此时,可以在try/catch代码块的后面加上finally代码段来处理这种情况。try/catch/finally的基本形式如下所示: try{ 可能发生异常的代码块; } catch(异常类型 异常对象名){ 异常处理代码块; … finally{ 无论是否抛出异常都要执行的代码;
17
public class Exam6_4{ public static void main(String [ ] args){ try{ device(Integer.parseInt(args[0])); }catch (ArithmeticException e){ System.out.println ("输入为零,产生异常,被catch捕获到"); } finally{ System.out.println ("不论有没有产生异常,都会被执行的代码段!"); static int device(int i){ return 10/i;
18
抛出异常 一个异常对象可以由Java虚拟机抛出,也可以由程序主动抛出。程序运行过程中,当Java 发现一个运行错误时, Java抛出一个异常对象。如果程序中遇到有些逻辑问题但不是Java的 异常,程序也可以主动抛出一个异常对象。
19
抛出异常 Java提供给程序主动抛出异常的语句是throw,其语法格式如下: Throw 异常对象
其中, throw是关键字, 异常对象是程序创建的指定异常类对象。 由throw语句抛出的异常也必须由try语句捕获并处理 public void set(int age) { if (age>0 && age<100) this.age = age; else throw new Exception("IllegalAgeData"); }
20
public class FinallyWorks {
static int count = 0; public static void main(String[] args) { while(true) { try { // post-increment is zero first time: if(count++ == 0) throw new Exception(); System.out.println("No exception"); } catch(Exception e) { System.out.println("Exception thrown"); } finally { System.out.println("in finally clause"); if(count == 2) break; // out of "while" }
21
抛出异常 如果一个方法的方法体将产生异常,而该方法体中不想处理或不能处理该异常,则可以 在方法声明时,采用throws子句声明该方法将抛出异常。 带有throws子句的方法声明格式如下: [修饰符]返回值类型方法([参数列表]) [throws 异常类] 其中, throws是关键字,异常类是方法要抛出的异常类,可以声明多个异常类,用逗号隔开。 throws子句不是一条独立的语句。 例如 public static int parseInt(String s) throws NumberFormatException
22
public class Exam6_6{ public static void main(String [ ] args){ try{ device(Integer.parseInt(args[0])); }catch (ArithmeticException e){ e.printStackTrace(); } static void device(int i) throws ArithmeticException{ if (i==0) throw new ArithmeticException("输入为零,请重新输入!"); else System.out.println ("10/"+i+"="+10/i);
23
方法覆盖中的异常 应用覆盖的规则 一致的声明(名称、参数) 不低于基类的存取权限 覆盖方法所抛出的异常不能比原方法多
24
Java异常处理 第三讲 自定义Java异常
25
自定义异常 为什么要创建异常 尽管Java的内置异常能够处理大多数常见错误,但有时还可能出现系统没有考虑到的异常,此时我们可以自己建立异常类型,来处理所遇到的特殊情况。 如何创建异常 只要定义Exception的一个子类就可以建立自己的异常类型。 自定义异常的基本形式如下 class 自定义异常 extends 父异常类名{ 类体; }
26
public class Exam6_7 extends Exception{
System.out.println ("输入为零,请重新输入!"); } class Test{ public static void main(String [ ] args) { try{ if (args[0].equals("0"){ throw new Exam6_7(); else{ System.out.println ("10/"+args[0] +"="+10/Integer.parseInt(args[0])); catch(Exception e){
27
class MyException extends Exception {
public MyException() {} public MyException(String msg) { super(msg); } public class Inheriting { public static void f() throws MyException { System.out.println( "Throwing MyException from f()"); throw new MyException(); } public static void g() throws MyException { "Throwing MyException from g()"); throw new MyException("Originated in g()"); public static void main(String[] args) { try { f();} catch(MyException e) { e.printStackTrace(); try { g();} catch(MyException e) {
28
正确使用异常注意事项 由于异常使用起来非常方便,以至于在很多情况下可能会滥用异常。但是,使用异常处理会降低程序运行的速度,如果在程序中过多地使用异常处理,程序的执行速度会显著地降低。 在可以使用简单的测试就能完成的检查中,不要使用异常来代替它。例如: if (ins!=null) //使用ins引用对象 { … } 不要过细地使用异常。最好不要到处使用异常,更不要在循环体内使用异常处理, 可以将它包裹在循环体外面。
29
正确使用异常注意事项 不要捕获了一个异常而又不对它做任何的处理。如: 对于有些异常,将其交给方法的调用者去处理是一种更好的处理办法。
try { …… //正常执行的代码 } catch(Exception e) { } 对于有些异常,将其交给方法的调用者去处理是一种更好的处理办法。 一个方法被覆盖时,覆盖它的方法必须抛出相同的异常或异常的子类。 如果父类抛出多个异常,那么重写(覆盖)方法必须扔出那些异常的一个子集,也就是说不能扔出新的异常。
30
例题 设计两个异常类,当输入参数低于170时产生TooShortException异常,而当输入参数高于180时产生TooTallException异常。编写一个检查类,其中的某一个方法产生以上两种异常。测试此程序。
Similar presentations