异常处理

异常机制
异常机制是指当程序出现错误后,程序如何处理。具体来说,异常机制提供了程序退出的安全通道。当出现错误后,程序执行的流程发生改变,程序的控制权转移到异常处理器。

传统的处理异常的办法是,函数返回一个特殊的结果来表示出现异常(通常这个特殊结果是大家约定俗称的),调用该函数的程序负责检查并分析函数返回的结果。这样做有如下的弊端:例如函数返回-1代表出现异常,但是如果函数确实要返回-1这个正确的值时就会出现混淆;可读性降低,将程序代码与处理异常的代码混爹在一起;由调用函数的程序来分析错误,这就要求客户程序员对库函数有很深的了解。

Java异常的层次结构
Throwable 类是 Java 语言中所有错误或异常的超类。
两个子类的实例,Error 和 Exception

Error: 用于指示合理的应用程序不应该试图捕获的严重问题。Java运行系统中的内部错误以及资源耗尽的情形。应用程序不应该抛出这种类型的对象(一般是由虚拟机抛出)。如果出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以,在进行程序设计时,应该更关注Exception体系。

Exception:它指出了合理的应用程序想要捕获的条件。
Exception体系包括运行时异常体系和其他非运行时异常的体系
运行时异常(RuntimeException)体系包括错误的类型转换、数组越界访问和试图访问空指针等等。处理RuntimeException的原则是:如果出现RuntimeException,那么一定是程序员的错误。例如,可以通过检查数组下标和数组边界来避免数组越界访问异常。
其他非运行时异常的体系这类异常一般是外部错误,例如试图从文件尾后读取数据等,这并不是程序本身的错误,而是在应用环境中出现的外部错误。

 
以上为我们常见的异常,以及异常的体系结构

异常处理基础
Java语言中处理异常主要是通过五个关键词来实现的,即try, catch, throw, rhrows和finally,用try来执行一段程序,如果出现异常,系统会抛出一个异常,可以通过类型来捕捉(catch,或是在最后(finally)由默认处理器来处理.
try{
 //程序块
}catch(Exception1  e){
 对Exception1  进行处理
} catch(Exception2  e){
 对Exception2  进行处理
}finally{
 最终处理块,不管异常是否被捕捉,这里都将执行.
}
示例package01
当Java运行时系统检测到除0时,它先构建一个新的异常对象,然后抛出这个异常,这导致程序停止执行,因为一旦抛出异常,异常处理程序必须捕获它并立即处理,如果不捕捉,Java会提供默认处理程序来捕捉异常.默认的程序处理会显示一个描述异常的字符串,打印异常发生处的堆栈追踪并终止程序.

尽管Java运行时系统提供的默认处理程序对调用来说很有用,但有时还会想自己处理异常,这样做有两个好处,首先,它允许你修正错误,其次,它防止程序自动终止,如果程序停止错误并在出现错误时打印了一个堆栈追踪,大部分用户会很困惑.
要防止和处理运行时错误,只需要将监控的代码包括在一个try块中,然后在try块后面紧跟一个catch子句,该子句指定了希望捕获异常类型.

多条catch语句
在某些情况下,一段代码可能引发一个以上的异常,要处理这种情况,可以指定更多的catch语句,每条语句用于捕获不同类型的异常,当抛出异常时,按顺序检查每个catch语句,其类型与异常相匹配的第一条语句被执行,在执行一条catch语句后,跳过其他语句并从try/catch块后的代码处继续执行.请看示例package02

在使用多条catch语句时, 异常子类必须在它的任何超类之前,这是因为使用超类的一条catch语句将捕获该类型的异常以及它的任何子类,因此,如果一个子类在它的超类之后,它将永远不会到达.还有在Java中,对不可到达的代码认为是一个错误.
请看示例package03

如果编译该程序,将收一条错误消息,表明第二条catch语句是不可到达的,因为异常已被捕获,由于ArithmeticException是Exception的一个子类,所以 第一条catch语句将处理基本所有Exception的异常,包括ArithmeticException,意味着第二条catch语句将永远不会执行,要解决这个问题,颠倒catch语句的即可.

嵌套的try语句
请看示例package04
示例中可以看到, 如果一个内部的try语句没有针对特定异常的catch处理程序,会将其异常抛出,外层的try捕捉到内层抛出的异常后,会检查有没有与之匹配的异常,如果有,则匹配,如果,Java运行时系统将处理该异常.

方法调用异常处理
请看示例package05
此例中,如果方法内的catch语句匹配的,则方法会抛出异常,但是main方法中的try语句捕捉到了此方法抛出的异常,所以会进行处理,所以此结果和上例子中的结果一样.

throw
使用throw语句可以显示地抛出一个异常,
形式为: throw ThrowableInstance;
必须是一个Throwable对象类型或Throwable的一个子类,基本类型以及非Throwable类,不能用做异常,有两种方式可以 一个Throwable对象,在catch语句中使用一个参数,或用new运算符创建一个.

在throw语句后面的代码不会执行,其后的任何语句将不再执行.然后检查离该语句最近的try块,查看是否有捕捉抛出异常的catch语句,如果找到了,则执行相应的catch块,否则,Java会用默认的异常处理进行处理,请看示例package06


throws
如果一个方法可能引起一个不能处理的异常,则它必须指明该行为以便方法的调用者能够警惕该异常,方法是在声明中包括一条throws子句. Throws子句列出了方法可能抛出的异常类型.示例package07

finally
当抛出异常时,方法内的程序会采取一种突变的,非线性的路线,这改变了方法内的正常程序流,根据方法的编码形式,异常甚至可能使方法过早地返回,而在有些情况下,例如,如是一个方法在进入时打开一个文件,在退出时关闭它,此时就不会希望由异常处理机制关闭被绕过的文件. finally块就是解决这种意外事件的.
finally块不管是否抛出一个异常,finally块都会执行,如果抛出一个异常,即使没有catch语句匹配这个异常,finally块也将执行. 示例package08

记住:如果finally块与一个try联系在一起,则一完成try就执行finally块.

创建自己的异常子类
尽管Java的内置异常可以处理大多数常见的错误,但有时还是需要创建自己的异常类型来处理应用程序中的特殊情况,其实,只要定义Exception子类即可.这个子类实现上不需要实现任何东西----只要它们存在于类型系统中,就可以作为异常使用.

Exception类没有定义任何方法,它只继承了Throwable提供的一些方法,因此,所有异常,包括自己创建的,都具有Throwable定义的方法.示例package09

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值