文档章节

Effective Java 第三版——73.抛出合乎于抽象的异常

o
 osc_w9s1w4o0
发布于 2019/03/31 09:24
字数 958
阅读 9
收藏 0

精选30+云产品,助力企业轻松上云!>>>

Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。

Effective Java, Third Edition

#73. 抛出合乎于抽象的异常

当一个方法抛出一个与它所执行的任务没有明显关联的异常时,这是令人不安的。在方法传播由低层(lower-level)抽象抛出的异常时,会经常发生这种情况。它不仅令人不安,而且用实现细节“污染”了上层的API。如果上层(higher layer)的实现在以后的版本中发生变化,那么它抛出的异常也会发生变化,可能会破坏现有的客户端程序。

为了避免这个问题,上层(higher layers)应该捕获低层( lower-level )的异常,并在它们的位置抛出可以用上层级别(higher-level )抽象来解释的异常。这个习语被称为异常转译:

// Exception Translation
try {
    ... // Use lower-level abstraction to do our bidding
} catch (LowerLevelException e) {
    throw new HigherLevelException(...);
}

以下的异常转转译的示例是来自AbstractSequentialList类,该类是List接口的骨架实现(skeletal implementation )(条目 20)。 在此示例中,异常转译由List <E>接口中的get方法规范强制要求的:

/**
 * Returns the element at the specified position in this list.
 * @throws IndexOutOfBoundsException if the index is out of range
 *         ({@code index <  0 || index >= size()}).
 */
public E get(int index) {
    ListIterator<E> i = listIterator(index);
    try {
        return i.next();
    } catch (NoSuchElementException e) {
        throw new IndexOutOfBoundsException("Index: " + index);
    }
}

如果较低级别的异常可能有助于调试导致较高级别异常的问题,则需要一种称为异常链(exception chaining )的特殊异常转译形式。低层异常(原因)传递给高层异常,高层异常提供一个访问器方法(Throwable的getCause方法)来检索低层异常:

// Exception Chaining
try {
    ... // Use lower-level abstraction to do our bidding
} catch (LowerLevelException cause) {
    throw new HigherLevelException(cause);
}

高级异常的构造方法将原因传递给一个感知链(chaining-aware)的父类构造方法,因此它最终被传递给Throwable的一个感知链的构造方法,比如Throwable(Throwable):

// Exception with chaining-aware constructor
class HigherLevelException extends Exception {
    HigherLevelException(Throwable cause) {
        super(cause);
    }
}

大多数标准异常都有感知链的构造方法。对于没有这样做的异常,可以使用Throwable的initCause方法设置原因。异常链接不仅允许你以编程方式访问原因(使用getCause),而且还将原因的堆栈跟踪集成到更高级别异常的堆栈跟踪中。

虽然异常转译优于低层异常的无意识传播,但不应过度使用。 在可能的情况下,处理较低层异常的最佳方法是通过确保较低级别的方法成功执行来避免异常。 有时可以通过检查更高级别方法的参数的有效性,然后再将它们传递到较低层来完成此操作。

如果不可能防止来自较低层的异常,那么接下来最好的事情就是让较高层静默地解决这些异常,从而使较高级别方法的调用者与较低级别的问题隔离开来。 在这些情况下,使用某些适当的日志记录工具(如java.util.logging)记录异常可能是适当的。 这允许程序员调查问题,同时把使用者和客户端代码隔离开。

总之,如果无法阻止或处理较低层的异常,那么使用异常转译,除非较低级别的方法恰好保证其所有异常都适用于较高级别。 异常链接提供了两全其美的优势:它允许抛出适当的更高级别异常,同时可以捕获失败分析的根本原因(条目 75)。

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Effective Java 第三版——73.抛出合乎于抽象的异常

Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。 73. 抛出合乎于抽...

M104
2019/03/29
0
0
Effective Java 第三版——73.抛出合乎于抽象的异常

Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。 73. 抛出合乎于抽...

林本托
2019/03/31
0
0
Effective Java 第三版——49. 检查参数有效性

Tips 《Effective Java, Third Edition》一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8...

M104
2018/10/15
0
0
Effective Java 第三版——49. 检查参数有效性

Tips《Effective Java, Third Edition》一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8...

osc_wme0cmft
2018/10/15
2
0
effective java 3rd中文版翻译

写在最前面 本 repo 从来没有授权过任何公众号进行发布转载,所有公众号的引流都是公众号拥有者的自发行动,和本 repo 无关 为什么搞这个项目,本项目初始创建的时候并不知道「effective jav...

whoisliang
04/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

asp.net core之NLog

NuGet添加 NLog.Web.AspNetCore。 <PackageReference Include="Microsoft.AspNetCore.App" /> 添加配置文件 新建一个文件nlog.config(建议全部小写,linux系统中要注意), 并右键点击其属性......

一介草民Coder
50分钟前
23
0
.NET中的struct和class有什么区别? - What's the difference between struct and class in .NET?

问题: .NET中的struct和class有什么区别? 解决方案: 参考一: https://stackoom.com/question/3OT/NET中的struct和class有什么区别 参考二: https://oldbug.net/q/3OT/What-s-the-differ...

富含淀粉
今天
23
0
android:layout_weight是什么意思? - What does android:layout_weight mean?

问题: I don't understand how to use this attribute. 我不明白如何使用这个属性。 Can anyone tell me more about it? 谁能告诉我更多关于它的事情? 解决方案: 参考一: https://stacko...

javail
今天
17
0
CSS背景不透明度[重复] - CSS Background Opacity [duplicate]

问题: This question already has an answer here: 这个问题已经在这里有了答案: How do I give text or an image a transparent background using CSS? 如何使用CSS为文本或图像提供透明背...

fyin1314
今天
31
0
node http 获取gb2312网页如何转为utf8

最初,我想当然认为是下述做法,但被证明是错误的 const http = require('http'), iconv = require('iconv-lite');const url = 'http://xxx';http.get(url, function(res) { var bo......

高延
今天
24
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部