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】函数式编程
No1: 函数式编程:即函数可以作为参数传递,也可以作为返回值 No2: map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的 ...
- Codeforces 1093D. Beautiful Graph【二分图染色】+【组合数】
<题目链接> 题目大意: 给你一个无向图(该无向图无自环,且无重边),现在要你给这个无向图的点加权,所加权值可以是1,2,3.给这些点加权之后,要使得任意边的两个端点权值之和为奇数,问总共 ...
- 李宏毅机器学习笔记3:Classification、Logistic Regression
李宏毅老师的机器学习课程和吴恩达老师的机器学习课程都是都是ML和DL非常好的入门资料,在YouTube.网易云课堂.B站都能观看到相应的课程视频,接下来这一系列的博客我都将记录老师上课的笔记以及自己对 ...
- 图片预览组件PhotoView
图片预览组件PhotoView PhotoView是一款图片预览组件,广泛应用于大图的查看.该组件支持图片手势缩放.旋转等功能.它可以很好的和ViewPager.Picasso等组件结合,实现各种复杂 ...
- BZOJ.4738.[清华集训2016]汽水(点分治 分数规划)
BZOJ UOJ 记\(val_i\)是每条边的边权,\(s\)是边权和,\(t\)是经过边数,\(k\)是给定的\(k\). 在点分治的时候二分答案\(x\),设\(|\frac st-k|=x\) ...
- 2017-9-11-Linux开机启动脚本
参考文章:https://www.magentonotes.com/ubuntu-config-autostart-shell-script.html 还是先开门见山的说,Linux需要添加开机启动程 ...
- CC2431 代码分析②-CC2431狂轰滥炸
CC2431 code review : CC2431 狂轰滥炸 在上一篇中的最后我们分析到CC2431 开始喊出第一声,这里我们逐步分析从第一声到后面的狂轰滥炸! 上代码 /************ ...
- 志愿者招募 [NOI2008] [鬼畜网络流]
Description 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的主管.布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志愿者.经过估算,这个项目需要N 天才能完 ...
- Could not commit JPA transaction RollbackException: Transaction marked as rollbackOnly
项目调试时,报以下错误: org.springframework.transaction.TransactionSystemException: Could not commit JPA transa ...
- Grok patterns 汇总
S3_REQUEST_LINE (?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawreques ...