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年出版,到现在已经将 ...
随机推荐
- HDU 1045 Fire Net 【二分图匹配】
<题目链接> 题目大意: 这题意思是给出一张图,图中'X'表示wall,'.'表示空地,可以放置炮台,同一条直线上只能有一个炮台,除非有'X'隔开,问在给出的图中最多能放置多少个炮台. 解 ...
- Linux学习之后台任务与定时任务(二十)
Linux学习之后台任务与定时任务 目录 后台任务 把进程放入后台 查看后台任务 将后台暂停的工作恢复到前台执行 将后台暂停的工作恢复到后台执行 定时任务 手动启动服务 将服务设置为自启动 用户的co ...
- muduo学习笔记(六) 多线程的TcpServer
目录 前言 多线程TcpServer EventLoopThreadPool 线程池设计模式 muduo中的使用 连接的建立.消息.销毁 on_connection on_message on_clo ...
- ctf study of jarvisoj reverse
[61dctf] androideasy 164求解器 50 相反 脚本如下: s='' a=113, 123, 118, 112, 108, 94, 99, 72, 38, 68, 72, 87, ...
- 10个非常有趣的Linux命令【转载】
Linux当中有很多比较有趣的命令,可以动手看看,很简单的. 1.rev命令 一行接一行地颠倒所输入的字符串. 运行: $rev 如输入:shiyanlou shiyanlou rev.jpg 2.a ...
- vue中的jsx
一.配置文件package.json { "name": "vuetest", "version": "1.0.0", ...
- 37_Reverse3_digit_Integer
描述 反转一个只有3位数的整数. 你可以假设输入一定是一个只有三位数的整数,这个整数大于等于100,小于1000. [ ] 您在真实的面试中是否遇到过这个题? 样例 123 反转之后是 321. 90 ...
- SQL Server中变量的声明和使用方法
网址:http://blog.sina.com.cn/s/blog_63d0c97a0100qpy7.html 声明局部变量语法: DECLARE @variable_name DataType 其中 ...
- window下安装PIL
PIL非官方库64 友情连接: https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/ ...
- Android强制关闭某个指定应用 “关闭应用”
强制关闭指定的应用程序: // 传入应用的包名即可kill掉应用 private void forceStopApp(String packageName) { ActivityManager am ...