Java的异常处理机制并不是只有将程序逻辑与异常处理分开的好处,程序设计的错误情况很多且难以估计,并没有人能保证自已所设计的程序完全无误,异常处理最重要的是为程序设计人员提供种种可能的异常情况,让程序设计人员能够掌握并设法排除。 Java编译器会检查程序语法等的相关错误,这些错误是属于“编译时期错误”,然而语法无误并不代表程序逻辑没有错误,逻辑上的错误会在程序执行时发生,这是属于“运行时错误”,而即使逻辑没有错误,也可能因为I/O、网路或甚至内存不足等情况而发生错误。 Java所处理的异常主要可分为两大类,一种是严重的错误,例如硬体错误或内存不足等问题,与此相关的类是位于java.lang下的Error类;另一种是非严重的错误,代表可以处理的状况,与此相关的是位于java.lang下的Exception类。 Error类与Exception类都继承自Throwable类,Throwable类拥有几个报告相关异常讯息的方法:
除了使用这些方法之外,我们也可以利用toString()取得异常对象的错误描述。 您所处理的异常通常都是衍生自Exception类,其中大部份是运行时异常(RuntimeException), 例如 ArithmeticException、ArrayIndexOutOfBoundsException等等,另外还有一些非运行时异常,例如 ClassNotFoundException(尝试载入类时失败所引发,例如类文件不存在)、InterruptedException(线程非 执行中而尝试中断所引发的异常)等等, 以下列出一些重要的继承架构: Throwable
Error(严重的系统错误) LinkageError ThreadDeath VirtualMachineError .... Exception ClassNotFoundException CloneNotSupportedException IllegalAccessException .... RuntimeException(运行时异常) ArithmeticException ArrayStoreException ClassCastException .... 属于RuntimeException衍生出来的类,是在运行时会发生的,不需要特别使用try-catch或是在函数上使用"throws"声明也 可以通过编译,例如您在使用数组时,并不一定要处理ArrayIndexOutOfBoundsException异常。 Exception下非RuntimeException衍生之异常如果有引发的可能性,则您一定要在程序中明确的指定处理才可以通过编译,例如当您使用 到BufferedReader类时,由于有可能引发IOException,您要不就在try-catch中处理,要不就在函数上使用throws表 示由调用它的函数来处理。 了解异常处理的继承架构是必须的,例如在捕捉异常对象时,如果父类异常对象撰写在子类异常对象之前被捕捉,则catch子类异常对象的区块将永远不会被执行,事实上编译器也会帮您检查这个错误,例如:
import java.io.*; 这个程序若在编译时将会产生以下的错误讯息: UseException.java:11: exception java.lang.ArithmeticException has already been caught
catch(ArithmeticException e) { ^ 1 error 要完成这个程序的编译,您必须更改异常对象捕捉的顺序,例如:
import java.io.*; 执行结果:
在撰写程序时,您也可以如上将Exception异常对象的捕捉撰写在最后,以便捕捉到所有尚未考虑到的异常,并进一步改进程序。 如果您要自订自已的异常类,您可以继承Exception类而不是Error,Error是属于严重的系统错误,您不用去处理它,您也可以继承 RuntimeException类,就如之前所说过的,这个异常不一用明确使用try-catch来处理也可以通过编译,但通常建议的是继承 Exception,至少这样的程序会是比较安全的,对于可处理的这些异常,您在程序中必须明确的解决它,如果没有,编译器会告诉您。 一些程序会自行继承相关的异常类,包括一些相关的异常讯息,它们也会在定义接口(interface)时于方法上声明throws某些类型的异常,然而 如果您在这些方法中发生了某些不是方法声明的异常(可能由于使用的底层技术不同而有这种情况),您就无法将之throw,只能自行撰写一些try.. catch来暗自处理掉,如果想要让这些异常丢出至上层,就要更多道的手续了,例如撰写一个类继承RuntimeException,在发生异常时将该异常包装至这个RuntimeException类中,然后再丢出。 |