三、异常的分类                                                    
1 .异常的分类                                                                         
Java编程语言中,异常有两种分类。java.lang.Throwable类充当所有对象的父类,可以使用异常处理机制将这些对象抛出并捕获。在Throwable类中定义方法来检索与异常相关的错误信息,并打印显示异常发生的栈跟踪信息。它有ErrorException两个基本子类。
错误(Error):JVM系统内部错误、资源耗尽等严重情况;
异常(Exception违例):其它因编程错误或偶然的外在因素导致的一般性问题,例如:对负数开平方根、空指针访问、试图读取不存在的文件、网络连接中断等。
当发生Error时,程序员根本无能为力,只能让程序终止。比如说内存溢出,不可能指望程序能处理这样的情况。而对于Exception,而有补救或控制的可能,程序员也可以预先防范,本章主要讨论Exception的处理。
为有效地描述异常状况、传递有关的异常信息,JDK中针对各种普遍性的异常情况定义了多种异常类型。其层次关系如下图所示: 9acf1d53tb86add8c4286&690

 


  Java 异常类继承层次
 
其中,RuntimeException(运行时异常)是指因设计或实现方式不当导致的问题。也可以说,是程序员的原因导致的,本来可以避免发生的情况。比如,如果事先检查数组元素下标保证其不超出数组长度,那么,ArrayIndexOutOfBoundsException异常从不会抛出;再如,先检查并确保一个引用类型变量值不为null,然后在令其访问所需的属性和方法,那么,NullPointerException也就从不会产生。
例题中的异常即属于RuntimeException,出错的原因是数组friends中只含有三个元素,当for循环执行到第四次时,试图访问根本不存在的第四个数组元素friends[3],因此出错。
包括IOException在内的其它违例,则可以认为是描述运行时遇到的困难,它通常由环境而并非程序员的原因引起,可以进行处理。例如:文件未找到或无效URL异常都经常容易出现。
读者可能的疑问是:既然运行错误经常发生,是不是所有的Java程序也都应采取这种异常处理措施?答案是否定的,Java程序异常处理的原则为:
1)对于ErrorRuntimeException,可以在程序中进行捕获和处理,但不是必须的;
2)对于IOException及其它异常,必须在程序中进行捕获和处理。
ArrayIndexOutOfBoundsException 属于RuntimeException,一个正确设计和实现的程序不会出现这种异常,因此可根据实际情况选择是否进行捕获和处理。现实生活中也采取了类似的原则:比如火灾(一般属人为因素导致的),由于会导致严重后果,因此可以在生产车间配备灭火器、准备好灭火措施,处理可能发生的火灾。但是,一般家庭不会准备发电机去应付可能出现的停电事故。
程序运行时,try语句块中的语句产生异常对象后,系统立即将之与后跟的catch语句块依次进行匹配性检查,只要异常对象是catch块中指定的类型或其子类类型,均认为匹配成功,一旦匹配成功则停止匹配检查、开始执行该catch块。
如果程序运行时,某个方法中的一个语句产生了一个没有在相应的try/catch块中处理的异常(肯定是ErrorRuntimeException),那么这个异常就被抛出到调用方法中。如果异常也没有在调用方法中被处理,它就被抛出到该方法的调用方法,直到异常被处理。如果异常对象一直被传递到main()方法仍为得到捕获处理,则程序将异常终止。
 
2 .预定义异常                                                                           
Java 编程语言中预先定义好的异常叫预定义异常,下面是可能遇到的更具共同性的异常中的几种:
- ArithmeticException —整数被0除,运算得出的结果。
如:int i =12 / 0
- NullPointerException —当对象没被实例化时,访问对象的属性或方法的尝试。
如:Date d= null;
System.out.println(d.toString());
- NegativeArraySizeException —创建带负维数大小的数组的尝试。
- ArrayIndexOutOfBoundsException —访问超过数组大小范围的一个元素的尝试。
- SecurityException —典型地被抛出到浏览器中,SecurityManager类将抛出applets的一个异常,该异常企图做下述工作(除非明显地得到允许):
访问一个本地文件。
打开主机的一个socket,这个主机与服务于applet的主机不是同一个。
在运行时环境中执行另一个程序