Effective Java阅读笔记(8)
Effective Java第9章 异常
57.只针对异常的情况才使用异常
不要将异常用于普通的控制流,也不要编写迫使它们这么做的API。
58.对可恢复的情况使用受检异常,对编程错误使用运行时异常
59.避免不必要地使用受检的异常
如果方法只是抛出单个受检的异常,仅仅一个异常就会导致该方法不得不外于try块中,在这些情况下,应该问自己,是否有别的途径来避免使用受检的异常。一种方法是把这个抛出异常的方法分成两个方法,其中第一个方法返回一个boolean,表明是否应该抛出异常。
60.优先使用标准的异常
以下为最常见的可重用异常:
IllegalArgumentException非null的参数值不正确;IllegalStateException对于方法调用而言,对象状态不合适;NullPointerException在禁止使用null的情况下参数值为null;IndexOutOfBoundsException下标参数值越界;ConcurrentModificationException在禁止并发修改的情况下,检测到对象的并发修改;UnsupportedOperationException对象不支持用户请求的方法。
61.抛出与抽象相对应的异常
更高层的实现应该捕获低层的异常,同时抛出可以按照高层抽象进行解释的异常,这就是异常转译。
如果不能阻止或者处理来自更低层的异常,一般的做法是使用异常转译,除非低层方法碰巧可以保证它抛出的所有异常对高层也合适才可以将异常从低层传播到高层。异常链对高层和低层异常都提供了最佳的功能:它允许抛出适当的高层异常,同时又能捕获底层的原因进行失败分析。
62.每个方法抛出的异常都要有文档
始终要单独地声明受检的异常,并且利用Javadoc的@throw标记,准确地记录下抛出每个异常的条件,但不要使用throws关键字将未受检的异常包含在方法的声明中。如果一个类中的许多方法出于同样的原因而抛出同一个异常,在该类的文档注释中对这个异常建立文档,这是可以接受的,而不是为每个方法单独建立文档。
63.在细节消息中包含能捕获失败的信息
为了捕获失败,异常的细节信息应该包含所有“对该异常有贡献”的参数和域的值。
64.努力使失败保持原子性
失败的方法调用应该使对象保持在被调用之前的状态。
部分实现途径:
设计一个不可变的对象。
在执行操作之前检查参数的有效性。
调整计算处理过程的顺序,使得任何可能会失败的计算部分都在对象状态被修改之前发生。
编写一段恢复代码。