Effective Java读书笔记(第9章-异常)

来源:互联网 发布:sql查2个字段重复数据 编辑:程序博客网 时间:2024/06/06 00:14

     第9章  异常

     第57条:只针对异常的情况才使用异常

     设计良好的API不应该强迫它的客户端为了正常的控制流而使用异常。异常是为了在异常情况下使用而设计的,不要将它们用于普通的控制流,也不要编写迫使它们这么做的API。

String[] str = {"aaa", "bbb", "ccc", "ddd", "eee"};try{int i = 0;while(true)System.out.println(str[i++].toString());}catch(ArrayIndexOutOfBoundsException e){}
     以上代码就是使用不当的例子,利用基于异常的模式来循环数组,这是不合理的,应该用标准模式。

String[] str = {"aaa", "bbb", "ccc", "ddd", "eee"};for(String s : str){System.out.println(s);}

    

     第58条:对可恢复的情况使用受检异常,对编程错误使用运行时异常

     java程序设计语言提供了三种可抛出结构:受检的异常(checked exception),运行时异常(run-time exception)和错误(error)。

     如果期望调用者能够适当地恢复,对于这种情况就应该使用受检的异常。

     如果程序抛出未受检的异常或者错误,往往就属于不可恢复的情形,继续执行下去有害无益。

     用运行时异常来表明编程错误。大多数的运行时异常都表示前提违例,前提违例指API的客户没有遵守API规范建立的约定。例如,数组访问的约定指明了数组的下标值必须是在0和数组长度减1之间。

     错误往往被JVM保留用于表示资源不足、约束失败,或者其他使程序无法继续执行的条件。


     第59条:避免不必要地使用受检的异常

     如果正确的使用API并不能阻止这种异常条件的产生,并且一旦产生异常,使用API的程序员可以立即采取有用的动作,这种负担就被认为是正当的。除非以上两条规则都成立,否则更适合于使用非受检的异常。


     第60条:优先使用标准的异常

     使用标准的异常有益于代码重用。

     常用的异常

异常使用场合IllegalArgumentException非null的参数值不正确IllegalStateException对于方法调用而言,对象状态不合适NullPointerException在禁止使用null的情况下参数值为nullIndexOutOfBoundsException下标参数值越界ConcurrentModificationException在禁止并发修改的情况下,检测到对象的并发修改UnsupportedOperationException对象不支持用户请求的方法

     第61条:抛出与抽象相对应的异常

     更高层的实现应该捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常。这种做法被称为异常转译。


     第62条:每个方法抛出的异常都要有文档

     始终要单独地声明受检的异常,并且利用javadoc的@throws标记,准确地记录下抛出每个异常的条件。


     第63条:在细节消息中包含能捕获失败的信息

     当程序由于未被捕获的异常而失败的时候,系统会自动地打印出该异常的堆栈轨迹。在堆栈轨迹中包含该异常的字符串表示法,即它的toString方法的调用结果。异常类型的toString方法应该尽可能多地返回有关失败原因的信息,这一点特别重要。


     第64条:努力使失败保持原子性

     失败的方法调用应该使对象保持在被调用之前的状态。有几种途径可以实现失败原子性。

     第一种,设计一个不可变的对象,如果对象不可变,失败原子性就是显然的。

     第二种,对于在可变对象上执行操作的方法,获得失败原子性最常见的办法是,在执行操作之前检查参数的有效性。

     第三种,编写一段恢复代码,由它来拦截操作过程中发生的失败,以及使对象回滚到操作开始之前的状态上。

     第四种,在对象的一份临时拷贝上执行操作,当操作完成之后再用临时拷贝中的结果代替对象的内容。


     第65条:不要忽略异常

     catch块中不能是空的,至少包含一条说明,解释为什么可以忽略这个异常。

0 0