您的位置:首页 > Web前端

EffectiveJava(笔记八) 异常

2017-07-10 15:48 218 查看

57. 只针对异常的情况才使用异常

try{
int i = 0;
while(true) range[i++].climb();
} catch(ArrayIndexOutOfBoundsException e) {
}


这段代码有什么作用? 看起来根本不明显, 这正是它没有真实被使用的原因, 这个循环企图访问数组边界之外的第一个数组元素时, 用抛出、 捕获、 忽略ArrayIndexOutOfBoundsException的手段来达到终止无限循环的目的, 为什么有人会优先使用基于异常的模式, 而不是用行之有效的模式呢? 他们企图利用Java的错误判断机制来提高性能, 因为VM对每次数组访问都要检查越界情况, 所以他们认为正常的循环终止测试被编译器隐藏了, 但是在for-each循环中仍然可见, 这无疑是多余的, 应该避免

因为异常机制的设计初衷是用于不正常的情形, 所以很少会有JVM实现试图对它们进行优化, 使得与先是的测试一样快速

把代码放在try-catch块中反而阻止了现代JVM实现本来可能执行的某些特定优化

对数组进行遍历的标准模式并不会导致冗余的检查, 有些现代的JVM实现会将它们优化掉

实际上, 在现代的JVM实现上, 基于异常的模式比标准模式要慢得多, 对于一个有100个元素的数组, 基于异常的模式比标准模式慢了2倍

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

59. 避免不必要地使用受检的异常

受检的异常是Java程序设计语言的一项很好的特性, 与返回代码不同, 它们强迫程序员处理异常的条件, 大大增强了可靠性, 但是过分使用受检的异常会使API使用起来非常不方便, 方法抛出多个受检的异常, 就得在多个catch块中处理这些异常, 异常的处理万一又会出现异常, 因此这种情况要拆分代码块, 分解受检的异常

60. 优先使用标准的异常

优先使用Java平台所提供的异常类

61. 抛出与抽象相对应的异常

当方法传递由低层抽象抛出的异常时, 往往会发生这种情况, 除了使人感到困惑之外, 这也让实现细节污染了更高层的API, 如果高层的实现在后续的发行版本中发生了变化, 它所抛出的异常也可能会跟着发生变化, 从而潜在地破坏现有的客户端程序, 为了避免这个问题, 更高的实现应该捕获低层的异常, 同时抛出可以按照高层抽象进行解释的异常

62. 每个方法抛出的异常都要有文档

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

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

为了捕获失败, 异常的细节信息应该包含所有”对该异常有贡献”的参数和域的值

64. 努力使失败保持原子性

一般而言, 失败的方法调用应该使对象保持在被调用之前的状态, 具有这种属性的方法被称为具有失败原子性

65. 不要忽略异常

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: