黑马程序员——异常处理

------- <a href="http://www.itheima.com" target="blank">android培训</a>、<a href="http://www.itheima.com" target="blank">java培训</a>、期待与您交流! ----------

在程序运行过程中,可能发生异常,也就是出现错误。出现错误的原因可能是由程序本身编写上的逻辑错误引起的,也有可能是在应用环境下,出现的外部错误。出现异常后,需要处理,java将程序中的异常包装成异常类——Exception。Exception继承自Throwable,同样继承自Throwable的类还有Error,但Error不希望被程序捕获处理,需由虚拟机自己处理,并使程序停止运行;Exception可以被程序捕获(catch)并处理。

异常抛出,可以是在程序运行时发生并由虚拟机抛出,也可以是由throw语句抛出。其中非RuntimeException只能由throw语句抛出,且必需在其方法名上标注throws语句(throws X_Exception),throws语句抛出的异常必须是方法中throw语句抛出异常的父类或同类。RuntimeException由throw语句抛出时,可以不在方法名上标注throws语句。由throws语句抛出非RuntimeException的方法在调用时必须处理异常或继续向上抛出异常。

对代码进行异常检查处理的格式为:

try{
      代码块
}
catch(X_Exception  xe){
      异常处理代码
}
finally{
      必须执行的代码
}
异常发生后,经过此格式的处理后将继续执行try—finally下面的代码,如果未做此处理(RuntimeException不会强制检查,运行时检查)或向上抛出了异常,则方法会直接返回,下面的代码不会再被执行。在try代码块内部,发生异常位置后的代码仍不得执行。

异常处理的一种设计模型是把try块和catch处理代码放入while循环中,捕获异常后做异常处理再重新调用try块中的内容,直到不再发生异常。但更多的设计是不再做这种恢复,因为这增加了代码编写和维护的困难,对于大型程序更是如此,因为异常可能会从许多地方抛出。

关于继承:
子类重写父类的带有throws语句(即会抛出异常的方法)的方法时,也必须抛出父类该方法抛出异常的同类或子类。

关于重新抛出异常:
通过try检查异常并通过catch捕获异常后,可以再次抛出该异常,此时抛出的异常带有原来的栈轨迹,如果调用异常的fillInStackTrace()方法(该方法返回Throwable对象),就会产生一个带有原来异常信息却带有新的抛出点栈轨迹的异常对象。另外,可以将非RuntimeException包装成RuntimeException上抛,方法如下:

try{
.../
}
catch(AException ae){
...
throw new RuntimeException(ae);
}

异常链:
捕获一个异常后,抛出另一个异常,同时希望把原来的异常保存下来,这被成为异常链。构造异常链,是通过把原来的异常对象传入新异常的构造方法产生新异常对象的方式构造的。Error、Exception和RuntimeException都有这样的构造方法,传入的都是Throwable对象。除了用构造函数的方法还可以调用新创建的异常的initCause(Throwable t)方法(Throwable的方法)将原来的异常初始化为新异常的cause。

finally子句:
finally后面花括号内的代码,是一定被执行的部分,无论是否发生异常,都会被执行,即使在try—finally中间有return语句,finally子句中的内容也会被执行。当要把除内存之外的资源恢复到它们的初始状态时,就要用到finally子句。这种需要清理的资源包括:已经打开的文件或网络连接,在屏幕上的图形,甚至可以是外部世界的某个开关。如果把这些动作放在catch子句中,可能会因为异常未被捕获而不得执行。
如果把finally子句和带标签的break和continue配合使用,在Java中就没必要使用goto语句了。
在try—finally语句中,如果继续向外抛出了异常1,而同时在finally子句中由抛出了异常2,未经处理的异常1会被异常2代替,外部只能捕获异常2。
在finally子句中如果有return语句,抛出异常的方法正常返回,如果仍向外部抛出了异常,此异常视为未发生,也不会被外部相应的catch捕获到。

关于方法重写时,异常的抛出声明:
子类重写父类方法时,抛出的异常必须是父类声明的异常的同类或子类或者不抛出异常;子类继承一个父类同时实现一个接口,接口和父类具有同一个方法时,父类抛出的异常是接口抛出异常的同类或子类或者不抛出异常。对于构造方法不用受此限制。

异常使用指南:
应该在以下情况下使用异常:
1)在恰当的级别处理问题。(在知道该如何处理的情况下捕获异常。)
2)解决问题并且重新调用产生异常的方法。
3)进行少许修补,然后绕过异常发生的地方继续执行。
4)用别的数据进行计算,以代替方法预计会返回的值。
5)把当前运行环境下能做的事情尽量做完,然后把相同的异常重新抛到更高层。
6)把当前运行环境下能做的事情尽量做完,然后把不同的异常抛到更高层。
7)终止程序。
8)进行简化。
9)让类库和程序更安全。(这既是在为调试做短期投资,也是在为程序的健壮性做长期投资)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值