1、Java程序设计,第六章 异常处理,异常的概念,异常(Exception)又称为例外、差错、违例等,是特殊的运行错误对象,对应Java语言中特定的运行错误机制。,没有处理错误的程序: read-file openTheFile; determine its size; allocate that much memory; closeTheFile; ,异常的概念,以常规方法处理错误 openFiles; if (theFilesOpen) determine the lenth of the file; if (gotTheFileLength) allocate that much memo
2、ry; if (gotEnoughMemory) read the file into memory; if (readFailed) errorCode=-1; else errorCode=-2; else errorCode=-3 ; else errorCode=-4;,异常的概念,观察前面的程序你会发现大部分精力花在出错处理上了.只把能够想到的错误考虑到,对以外的情况无法处理程序可读性差由谁处理错误的职责不清,以致造成较大的潜伏问题。,异常处理机制,在一个方法的运行过程中,如果发生异常,则这个方法生成代表异常的一个对象,并将其交给运行时系统。这一过程称为抛出(throw)异常。运行时
3、系统接收到异常对象后,寻找处理异常的代码,并将当前异常对象交给其处理。这一过程称为捕获(catch)异常。若运行时系统找不到处理异常的代码,则Java程序退出运行。,异常的概念,用异常的形式处理错误read-File; try openTheFile; determine its size; allocate that much memory; closeTheFile; catch(fileopenFailed) dosomething; catch(sizeDetermineFailed) dosomething; catch(memoryAllocateFailed) dosomethi
4、ng; catch(readFailed) dosomething; catch(fileCloseFailed) dosomething; ,异常的分类,异常是一个对象,它继承自Throwable类.Error:由Java虚拟机生成并抛出,Java程序不做处理.Exception:其它由于编程错误及偶然的外在因素导致的一般性问题。一般我们所说的异常都是指Exception及其子类。,异常处理,Exception也有自己的方法和属性。它有两个构造方法: public Exception(); public Exception(String s); s通常是对该例外所对应 的错误的描述。 Exc
5、eption类还继承了父类的方法,常用的: public String toString(); 返回描述当前Exception 类信息的字符串。 public void printStackTrace(); 在当前的输出上 打印当前例外对象的堆栈使用轨迹,即程序使用 执行了哪些对象、类,使得产生了例外。,Exception的子类分为RuntimeException和非RuntimeException。前者是一种设计和实现时的问题,如数组越界等,这种异常可以通过编程避免。后者是在程序运行过程中由环境原因造成的异常。用户定义的异常这类异常是由Exception或其子类所派生出来的类,用于处理与具体
6、应用相关的异常。,异常的分类,Throwable,Error,Exception,RuntimeException,缺省的异常处理程序,由用户捕获或声明并处理,不做处理,用户自己产生的异常,要处理,常见的异常ArithmeticExceptionArrayIndexOutOfBandsExceptionArrayStoreExceptionIOExceptionFileNotFoundExceptionNullPointerExceptionMalformedURLExceptionNumberFormatExceptionOutOfMemoryException,如果在使用能够产生异常的方法
7、而没有捕获和处理,将不能通过编译,抛出异常,所有的系统定义的运行异常都可以由系统自动抛出。 用户程序自定义的异常不能由系统自动抛出,必须借助于 throw语句定义何种情况算是产生了异常对应的错误,并且应该抛出这个异常类的对象。 throw 异常对象; 注:1、throw语句一般被定义为满足一定条件时执行。如放在if分支中。 2、使用throw语句的方法,或者调用其他类的有异常抛出的方法时,应在方法头定义中增加throws异常类名列表。,异常处理,捕获异常当一个异常被抛出时,应该由专门的语句来接收这个异常对象。一个异常类的对象被捕获后,程序就会跳转至专门的异常处理语句块,或者直接跳出当前程序和J
8、VM。异常对象是依靠catch语句块(异常处理语句块)来捕活和处理异常的。,异常处理,try catch(异常类名 异常形参名) catch(异常类名 异常形参名) finally catch语句可以有一个或多个,紧跟在try语句块后面,finally语句可以任选,无论try代码块中是否发生异常,finally块中的语句都会执行。,异常处理,多异常的处理在实际应用中,一个try块可能产生多种不同的异常,如果希望采取不同的方法来处理,就需要使用多异常处理机制。多异常处理通过在一个try块后面定义若干个catch块来实现。当try抛出异常时,程序首先转向第一个catch,查看是否能够接收该异常。,
9、异常处理,多异常的处理接收异常指异常对象与catch的参数的匹配:1、异常对象与参数属于相同的例外类2、异常对象属于参数例外类的子类3、异常对象实现了参数所定义的接口如果被第一个catch接收,则程序直接执行这个块,完毕后退出当前方法,try块中没有执行的语句及其他catch块将被忽略。否则,一次匹配其他的catch块,直到找到一个可以接收该异常对象的catch块。,异常处理,多异常的处理如果所有的catch都不匹配,则程序会返回到调用该方法的上层方法。如果这个上层方法定义了与所产生的异常相匹配的catch块,则会跳到这个catch块,否则继续回溯。如果最终都没有找到,则这是系统一般会终止程序
10、,然后打印除相关的异常信息。如果没有异常发生,那么所有的catch块都会被忽略。,异常处理,设计catch由于catch块是按照先后排列顺序执行的,所以一般来讲将处理较为具体的和常见的异常的catch块放在前面,而与多种异常相匹配的catch块放在靠后的位置。 catch块根据异常的不同执行不同的操作,一般来讲是将异常和错误的信息打印出来,方便修改调试程序。,示例1,class ExcepTest public static void main(String args) int b=0; int a; try a=4/b; /自动抛出异常 catch(ArithmeticException e
11、) /捕获异常后,处理 System.out.println(“divided by 0”); ,class ExcepTest public static void main(String args) int b=0; int a; a=4/b; ,例6-1,public class ExceptionIndexOutOfpublic static void main(String args) String friends=lisa,bily,kessy;tryfor(int i=0;i5;i+)System.out.println(friendsi);catch(ArrayIndexOut
12、OfBoundsException e) System.err.println(index err); System.out.println(n this is the end); ,2.8.4声明异常,一个方法不处理它产生的异常,而是沿着调用层次向上传递,由调用它的方法来处理这些异常,叫声明异常.声明异常的方法在产生异常的方法名后面加上要抛出(throws)的异常的列表void compute(int x)throws ArithmeticException returnType methodName(parameterlist) throws exceptionList,声明异常,例:若因
13、某种原因不想在计算方法中处理异常,public method1() int x; try x=System.in.read(); compute(x); catch(IOException ioe) System.out.println(“read error”); catch(ArithmeticException e) System.out.println(“devided by 0”); ,public int compute(int x) throws ArithmeticException return z=100/x;,2.8.4声明异常,例:说出程序执行结果public clas
14、s exception1 void Proc(int sel) throws ArithmeticException, ArrayIndexOutOfBoundsException System.out.println(“In Situation + sel ); if (sel=0) System.out.println(no Exception caught); return; else if(sel=1) int iArray=new int4; iArray10=3; ,例6-3,6-4,import java.io.*;public class ExceptionThrowsToOt
15、herpublic static void main(String args) try System.out.println(=Before=);readFile();System.out.println(=after=); catch(IOException e)System.err.println(e); public static void readFile()throws IOException FileInputStream in=new FileInputStream(myFile.txt); int b; b=in.read(); while(b!=-1)System.out.p
16、rint(char)b);b=in.read(); in.close(); ,import java.io.*;public class ExceptionThrowsToOtherpublic static void main(String args) readFile1(); public static void readFile1 FileInputStream in=new FileInputStream(myFile.txt); int b;b=in.read();while(b!=-1) System.out.print(char)b); b=in.read(); in.close
17、();catch(IOException e)System.out.println(ioexception!); ,自定义异常类,自定义异常不是由Java系统监测到的异常(下标越界,被0-除等),而是由用户自己定义的异常.用户定义的异常同样要用try-catch捕获,但必须由用户自己抛出 throw new MyException.异常是一个类,用户定义的异常必须继承自Throwable或Exception类,建议用Exception类.,例6-5,class MyException extends Exception private int id;MyException ();public
18、MyException (String message , int id)super( message); this.id=id;public int getId() return id;,public class TestMyException private int num;public void setNum(int num) throws MyException if(num0) throw new MyException(输入号码有误!,3);public static void main(String args) TestMyException a=new TestMyExcept
19、ion();trya.setNum(10);catch(MyException e)System.out.println(e.toString()+e.getId();finallySystem.out.println(Hello World!);,自定义异常类,形如:class MyException extends Exception.; 例1 :计算两个数之和,当任意一个数超出范围时,抛出自己的异常,public class NumberRangeException extends Exception public NumberRangeException(String msg) sup
20、er(msg); ,自定义异常类,import java.util.*;import java.io.*;public class SelfException public SelfException() public int selfExceptionTest(int int1,int int2) throws NumberRangeException if(int120)|(int220) throw new NumberRangeException(“数值超出了指定的范围!); else int1=int1+int2; return int1; ,自定义异常类,public static
21、 void main(String args)SelfException self= new SelfException();tryint calc = self.selfExceptionTest(18,19);String answerStr= String.valueOf(calc);System.out.println(Answer: +answerStr); calc = self.selfExceptionTest(8,9);System.out.println(Answer: +answerStr);answerStr= String.valueOf(calc);catch(Nu
22、mberRangeException e)System.out.println(Catch : +e); ,6.2.2 重抛异常与异常链接,(1)将当前捕获的异常再次抛出,格式为 throw e;(2) 重新生成一个异常,并抛出,如 throw new Exception(“some message”);(3) 重新生成并抛出一个新的异常,该异常 中包含当前异常的信息,如:throw new Exception(“some message”,e);,小结,在Java中,异常处理的目的是使用尽可能精简的代码创建大型、可靠的应用程序,同时排除程序里那些不能控制的错误。通过本节学习,使我们主要学习了如下主要内容:异常的概念异常的分类声明异常抛出异常捕获并处理异常自定义异常类,