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,并且适用与相同的警告:如果要在没有外部同步的情况下同时访问对象,或者被外部转换状态,则此重构是不合适的,因为对象的状态可能是在对actionPermittedaction的调用之间进行更改。如果单独的actionPermitted方法会重复action方法的工作,则可能会因性能原因而排除重构。

总之,如果谨慎使用,检查异常可以提高程序的可靠性;当过度使用,会使API难以使用。如果调用者无法从失败中恢复,则抛出未检查异常。如果恢复是可能的,并且希望强制调用者处理异常条件,那么首先考虑返回Optional的。只有当在失败的情况下,无法提供充分的信息时,才应该抛出一个检查的异常。

Effective Java 第三版——71. 避免不必要地使用检查异常的更多相关文章

  1. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  2. 《Effective Java 第三版》新条目介绍

    版权声明:本文为博主原创文章,可以随意转载,不过请加上原文链接. https://blog.csdn.net/u014717036/article/details/80588806前言 从去年的3月份 ...

  3. Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  4. Effective Java 第三版——7. 消除过期的对象引用

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  5. Effective Java 第三版——10. 重写equals方法时遵守通用约定

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java 第三版——14.考虑实现Comparable接口

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  7. Effective Java 第三版——18. 组合优于继承

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  8. Effective Java 第三版——21. 为后代设计接口

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——32.合理地结合泛型和可变参数

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. 001.CDN概述

    一 互联网应用质量概述 1.1 互联网应用质量 互联网应用质量指标--QoE,其主要指标: 服务成功率:指用户所请求的服务成功完成的几率. 服务建立时间:指从服务请求到服务呈现所花费的时间,并且会因为 ...

  2. java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/HBaseConfiguration] with root cause

    在用Java web和hbase连接时,报出来这个错误,一开始我以为是hbase导入的包位置不对,不从build path那里导入,而是从WEB-INF下的lib中导入,尝试了之后结果仍是这个错误 十 ...

  3. 编辑datagridview单元格

    以这3种为例,最简单的是第三种,直接让单元格处于可编辑状态,当完成编辑后触发CellEndEdit事件,最后对输入的数据进行处理. private DateTimePicker dtp = new D ...

  4. skatebroads

    skateboardsn.滑板( skateboard的名词复数 ) == skateboard英 [ˈskeɪtbɔ:d]  . 斯给特博得. 美 [ˈskeɪtbɔ:rd] n.滑板复数: ska ...

  5. id生成器,分布式ID自增算法(Snowflake 算法)

    接口: /** * id生成器 */ public interface IdGenerator { String next(); } 实现类: /** * 分布式ID自增算法<br/> * ...

  6. Maya插件开发的几种方式归纳

    目前仅仅是一时兴趣,想要探索一下Maya插件开发的具体方法,但因为没有时间所以只起了个头 首先来到Autodesk Developer Network http://usa.autodesk.com/ ...

  7. BZOJ.3631.[JLOI2014]松鼠的新家(树上差分)

    题目链接 树剖/差分裸题.. //28260kb 584ms #include <cstdio> #include <cctype> #include <algorith ...

  8. [PA2014]Zadanie

    [PA2014]Zadanie 题目大意: 一棵\(n(n\le3\times10^5)\)个点的树,每个点上有\(a_i\)个人.树上所有人到\(i\)号点距离之和为\(b_i\).已知\(\{b_ ...

  9. Linux之nginx反向代理+三台web+nfs共享存储实现集群配置

    作业四:nginx反向代理+三台web+nfs共享存储实现集群配置 在各个web服务器上挂载nfs [root@localhost nginx]# mount -t nfs 192.168.152.1 ...

  10. IO流(6)—转换流

    1.处理流之二:转换流 InputStreamReader和OutputStreamWriter 2.当作用的文件就是一个文本文件且使用字节流传输时,需要把它转换成字符流,再在外面加上缓冲流以加速传输 ...