• 1. 第9讲 异常处理 一个程序在执行时期可能会遇到一些非预期的或不正常的错误。Java的异常处理机制,便是提供便利又强大的执行时期错误处理功能,来处理这类的情况。异常处理的目的,不是要避免异常,而是在异常发生时设法使损失降低到最小。
  • 2. 一、异常的概念在Java中,将错误分作异常(Exception)与错误(Error)两大类。 Exception类描绘着一些由程序本身及环境所产生的错误;Error类则描绘一些较少会发生的内部系统错误。 异常(Exception)可以被抓住并处理,但错误(Error)发生时,通常不太能做什么,只能通知用户关闭程序。
  • 3. 一个Java异常,指的是一个继承Throwable类之类的实例。 Throwable类有两个子类:Exception与Error。它们均被放在java.lang包中。而其再往下的子类,则是被放在不同的包中。
  • 4. 二、异常处理机制 Java中,所有的异常都是用类表示的,异常发生时会生成某个异常类的对象。
  • 5. 异常类的顶级父类Exception类: 构造函数: public Exception() //系统提示异常信息 public Exception(String s) /*接收字符串参数传入的信息,对 异常对象所对应的错误进行描述。*/ 从Throwable继承的常用方法: public String toString() //返回当前Exception类信息的字符串 public void printStackTrace() //向屏幕输出异常信息
  • 6. 常见的异常类ArithmeticException:算术异常 ArrayIndexOutOfBandsException:数组越界 ArrayStoreException:数组存储空间不足 IOException:输入输出异常 FileNotFoundException:没有找到指定文件 NullPointerException:访问一个空对象成员 MalformedURLException:URL格式异常 NumberFormatException:数据格式异常
  • 7. 三、异常处理方式异常处理主要有三种: 1.对于运行时异常可以不做处理,这时系统将采用缺省的处理器进行处理,打印Exception的字符值和发生异常的地点。 2.将可能发生异常的程序区块用try…catch的方式包起来。若发生了异常,程序会依照所发生的异常的种类,而跳到该异常种类的catch区去做异常处理。
  • 8. try…catch的形式try { //可能会发生异常的程序区块; } catch(异常类1 异常对象1) { //异常处理程序1 } catch(异常类2 异常对象2) { //异常处理程序2 } …… finally { //最终处理程序 ,可省略 //无论是否出现异常,都执行 }异常的类型是通过异常类来描述的。异常类是一种特殊的类,平时并不出现,在发生异常时,Java会自动产生一个异常对象,并把它“抛出”try块之外,抛出的异常对象与各个catch块进行匹配。 匹配原则:如果抛出的异常对象属于catch块里的异常类,或者属于该异常类的子类,则认为异常对象与catch块匹配
  • 9. 3.不在当前方法内处理异常,而是把异常抛出到调用方法中,所以在方法的开头,可声明在此方法中throws的异常类。然后在方法中,遇到异常发生条件成立时,用throw将异常触发。<方法名称>(<参数>)[throws<异常类1>,<异常类2>…] { if(异常条件1成立) throw new 异常类1(); if(异常条件2成立) throw new 异常类2(); …… }
  • 10. 四、捕获异常例: Exc0.java(无异常处理) class Exc0{ public static void main(String args[]){ int d=0; int a=42/d; } }
  • 11. 例:exc1.java(加入异常处理之后) class exc1{ public static void main(String args[]){ try{ int d=0; int a=42/d; } catch(ArithmeticException e){ System.out.println("被零除"); } } }加入异常处理后,在偶尔发生异常时程序也不会中断,而是消除异常以后继续执行下去。这就避免了类似“被0除”一类的小错误影响整个系统的运行。
  • 12. 例: MultiCatch.javaclass MultiCatch{ public static void main(String args[]){ try{ int a=args.length; System.out.println("a="+a); int b=42/a;int c[]={1}; c[42]=99; } catch(ArithmeticException e){ System.out.println("被零除:"+e); } catch(ArrayIndexOutOfBoundsException e){ System.out.println("数组越界:"+e); } } }异常捕获机制虽然功能强大,但它只能捕获已给出的异常,如果一个异常不在catch的范围内,则无法捕获。解决的办法有二: 1.增加一个catch块来捕获相对应的异常; 2.捕获更加通用的异常,如RuntimeException运行期异常或最通用的Exception异常。
  • 13. 关于RuntimeException的几点说明RuntimeException包括运行时各种常见的异常,如算术异常,数组下标越界异常等。 由于RuntimeException包括运行期的大部分异常,因此它应当放在最下面一个catch块中,否则就覆盖了其后的各种特定的异常处理。
  • 14. 五、抛出异常1. throw语句用来明确的抛出一个“异常”。程序会在throw语句后立即终止,转向try…catch寻找异常处理方法,不再执行throw后面的语句。例:ThrowDemo.java
  • 15. 2. throws用来声明一个方法可能抛出的各种异常,用在方法的首部,说明该方法会抛出但不捕获异常,然后可以在方法体内用throw将异常触发。
  • 16. 例:ThrowsDemo.javaclass ThrowsDemo{ static void procedure() throws IllegalAccessException{ System.out.println("内部过程"); throw new IllegalAccessException("抛出异常示例"); } public static void main(String args[]){ try{ procedure(); } catch (IllegalAccessException e){ System.out.println("捕捉异常"+e); } } }
  • 17. 六、自定义异常我们也可以设定自己的异常,步骤分为两步:建立自己的异常类;在合适的位置抛出一个这个异常。 所有的异常类都是继承自Exception类,在其中编写两个构造函数即可。如: class MyException extends Exception { public MyException() {} public MyException(String msg) { super(msg); } }
  • 18. 接下来便可用catch来捕获自定义异常类,如: try { . . . // 其中包括抛出自定义异常的语句 } catch (MyException e) { String errStr; errStr = e.getMessage(); System.out.println(errStr); } 例:ExceptDemo2.java
  • 19. 异常处理具有相当的难度,因为它要求编程人员预先估计可能会发生什么异常,以及这些异常可能会造成什么后果,发生每种错误时如何补救,这需要相当的经验才行。 再次强调,异常处理不是消除错误,而是在错误发生时将影响降到最低,尽可能保证程序在发生小的错误时还能够基本正常运行。