Effective Java 第三版——71. 避免不必要地使用检查异常
Tips
书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code
注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。

71. 避免不必要地使用检查异常
许多Java程序员不喜欢检查异常,但如果使用得当,他们可以改进API和程序。 与返回码和未检查异常不同,它们迫使程序员处理异常问题,增强可靠性。 也就是说,在API中过度使用检查异常会使它们使用起来不那么令人愉快。 如果方法抛出检查异常,则调用它的代码必须在一个或多个catch块中处理它们,或者声明抛出它们并向上传播。 无论哪种方式,它都会给API的使用者带来负担。这种负担在Java 8中加重了,因为抛出检查异常的方法不能直接在Stream中使用(条目45——48)。
如果不能通过正确使用API来防止异常情况,并且使用API的程序员在遇到异常时可以采取一些有用的操作,那么这种负担是合理的。除非满足这两个条件,否则可以使用未检查异常。作为最后的检验(litmus test),可以问问自己:程序员将如何处理异常。这是最好的办法吗?
} catch (TheCheckedException e) {
throw new AssertionError(); // Can't happen!
}
或者这样:
} catch (TheCheckedException e) {
e.printStackTrace(); // Oh well, we lose.
System.exit(1);
}
如果程序员不能做得更好,则需要一个未检查异常。
如果方法抛出的检查异常是惟一的,那么检查异常给程序员带来的额外负担就会大得多。如果还有其他方法,则该方法必须已经出现在try块中,并且最多需要另一个catch块。如果一个方法抛出单个检查异常,那么这个异常就是该方法必须出现在try块中,并且不能直接在Stream中使用。在这种情况下,有必要问问自己是否有办法避免检查异常。
消除检查异的最简单方法是返回所需结果类型的Optional(条目 55)。该方法只返回一个空的Optional,而不是抛出一个检查的异常。这种方法的缺点是,该方法不能返回任何详细说明其无法执行所需计算的额外信息。相反,异常具有描述性类型,并且可以导出方法来提供额外的信息(条目 70)。
还可以通过将抛出异常的方法分解为两个方法,将检查异常转换为未检查异常,第一个方法返回一个boolean值,表示是否抛出异常。 这个API重构将调用序列:
// Invocation with checked exception
try {
obj.action(args);
} catch (TheCheckedException e) {
... // Handle exceptional condition
}
转换为:
// Invocation with state-testing method and unchecked exception
if (obj.actionPermitted(args)) {
obj.action(args);
} else {
... // Handle exceptional condition
}
这种重构并不总是合适的,但是它可以使API更加舒适。 虽然后者调用序列并不比前者更漂亮,但重构的API更灵活。 如果程序员知道调用将成功,或者满足于让线程在失败时终止,那么重构也允许这个简单的调用序列:
obj.action(args);
如果怀疑普通的调用序列会成为常态,那么API重构可能是合适的。生成的API本质上与条目 69中的状态测试方法API,并且适用与相同的警告:如果要在没有外部同步的情况下同时访问对象,或者被外部转换状态,则此重构是不合适的,因为对象的状态可能是在对actionPermitted和action的调用之间进行更改。如果单独的actionPermitted方法会重复action方法的工作,则可能会因性能原因而排除重构。
总之,如果谨慎使用,检查异常可以提高程序的可靠性;当过度使用,会使API难以使用。如果调用者无法从失败中恢复,则抛出未检查异常。如果恢复是可能的,并且希望强制调用者处理异常条件,那么首先考虑返回Optional的。只有当在失败的情况下,无法提供充分的信息时,才应该抛出一个检查的异常。
Effective Java 第三版——71. 避免不必要地使用检查异常的更多相关文章
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
- 《Effective Java 第三版》新条目介绍
版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...
- Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——7. 消除过期的对象引用
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——10. 重写equals方法时遵守通用约定
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——14.考虑实现Comparable接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——18. 组合优于继承
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——21. 为后代设计接口
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——32.合理地结合泛型和可变参数
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- 【python】web开发
No1: hello.py def application(environ,start_response): start_response('200 OK',[('Content-Type','tex ...
- HDU2255 奔小康赚大钱 (最大权完美匹配) 模板题【KM算法】
<题目链接> 奔小康赚大钱 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊 ...
- Ajax技术使用(一)
Ajax技术使用 目录 AJAX介绍 XMLHttpRequest 请求和响应 onreadystatechange 事件 AJAX介绍 什么是 AJAX AJAX = 异步 JavaScript 和 ...
- XamarinEssentials教程移除键值首选项的键值
XamarinEssentials教程移除键值首选项的键值 如果开发者不再使用首选项中的某一项时,可以将该项移除掉.此时可以使用Preferences类的Remove()方法,该方法可以将存在于首选项 ...
- Halcon 常用算子使用场合
Chapter 1 :Classification 1.1 Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一个训练样本添加到一个高斯混合模型的训 ...
- BZOJ.5461.[PKUWC2018]Minimax(DP 线段树合并)
BZOJ LOJ 令\(f[i][j]\)表示以\(i\)为根的子树,权值\(j\)作为根节点的概率. 设\(i\)的两棵子树分别为\(x,y\),记\(p_a\)表示\(f[x][a]\),\(p_ ...
- BZOJ.4402.Claris的剑(组合 计数)
BZOJ 因为是本质不同,所以考虑以最小字典序计数. 假设序列最大值为\(m\),那么序列有这两种情况: \(1\ (1\ 2\ 1\ 2...)\ 2\ (3\ 2\ 3\ 2...)\ 3\ (4 ...
- SpringIOC和DI
1.Spring的概念 Spring的绿草丛(一) Spring轻量级框架, Java EE的春天,当前主流框架目标使现有技术更加易用,推进编码最佳实践内容IoC容器AOP实现数据访问支持简化JDBC ...
- shell脚本使用技巧3--函数调用
定义函数 function fname() { statements; } 或者 fname() { statements; } 传递参数给函数: fname arg1 arg2; ex: 函数参数定 ...
- java第二周的学习知识
1.java基本运行单位是类,类的组成成员为成员变量和方法.成员变量的种类有public,default(就是不写),protected,private.public:public可以修饰类,数据成员 ...