1700448753
1700448754
}
1700448755
1700448756
//保留原始异常信息
1700448757
1700448758
public IOException(Throwable cause){
1700448759
1700448760
super(cause);
1700448761
1700448762
}
1700448763
1700448764
}
1700448765
1700448766
在IOException的构造函数中,上一个层级的异常可以通过异常链进行传递,链中传递异常的代码如下所示:
1700448767
1700448768
try{
1700448769
1700448770
//Do Something
1700448771
1700448772
}catch(Exception e){
1700448773
1700448774
throw new IOException(e);
1700448775
1700448776
}
1700448777
1700448778
捕捉到Exception异常,然后把它转化为IOException异常并抛出(此种方式也叫作异常转译),调用者获得该异常后再调用getCause方法即可获得Exception的异常信息,如此即可方便地查找到产生异常的根本信息,便于解决问题。
1700448779
1700448780
结合上一个建议来看,异常需要封装和传递,我们在进行系统开发时不要“吞噬”异常,也不要“赤裸裸”地抛出异常,封装后再抛出,或者通过异常链传递,可以达到系统更健壮、友好的目的。
1700448781
1700448782
1700448783
1700448784
1700448786
编写高质量代码:改善Java程序的151个建议 建议112:受检异常尽可能转化为非受检异常
1700448787
1700448788
为什么说是“尽可能”的转化呢?因为“把所有的受检异常(Checked Exception)都转化为非受检异常(Unchecked Exception)”这一想法是不现实的:受检异常是正常逻辑的一种补偿处理手段,特别是对可靠性要求比较高的系统来说,在某些条件下必须抛出受检异常以便由程序进行补偿处理,也就是说受检异常有合理的存在理由,那为什么要把受检异常转化为非受检异常呢?难道说受检异常有什么缺陷或不足吗?是的,受检异常确实有不足的地方:
1700448789
1700448790
(1)受检异常使接口声明脆弱
1700448791
1700448792
OOP(Object Oriented Programming,面向对象程序设计)要求我们尽量多地面向接口编程,可以提高代码的扩展性、稳定性等,但是一旦涉及异常问题就不一样了,例如系统初期是这样设计一个接口的:
1700448793
1700448794
interface User{
1700448795
1700448796
//修改用户名密码,抛出安全异常
1700448797
1700448798
public void changePassword()throws MySecurityException;
1700448799
1700448800
}
1700448801
1700448802
随着系统的开发,User接口有了多个实现者,比如普通的用户UserImpl、模拟用户MockUserImpl(用作测试或系统管理)、非实体用户NonUserImpl(如自动执行机、逻辑处理器等),此时如果发现changePassword方法可能还需要抛出RejectChangeException(拒绝修改异常,如自动执行机正在处理任务时不能修改其密码),那就需要修改User接口了:changePassword方法增加抛出RejectChangeException异常,这会导致所有的User调用者都要追加对RejectChangeException异常问题的处理。
[
上一页 ]
[ :1.700448753e+09 ]
[
下一页 ]