Java异常转译(exception translation)的使用

什么是异常转译(exception translation)

在Java中,我们通常使用try-catch语句捕获异常,进行异常处理。但有些时候,我们使用try-catch捕获一个异常,但却不进行异常处理,反而是抛出另一个异常,这就称为异常转译。如下所示,

try {
	Method(); //某个会抛出Exception1异常的函数
} catch (Exception1 e) {
	throw new Exception2();
}

从上述代码我们很容易理解异常转译这个名字的内涵——将异常Exception1转译为Exception2

为什么要进行异常转译

第一次看见这样的代码可能会产生疑惑——使用try-catch语句通常是用来捕获异常并进行处理,但上述代码却在捕获异常后又抛出了另一个异常,既然终究会抛出一个异常,那么何必再多此一举使用try-catch呢?直接抛出Exception1不好吗?

这样做的原因是,在某些时候,高层实现和低层异常之间的关系不明显,直接抛出低层异常会使调用高层实现的客户端看到异常时不知所措。

下面用JDK的AbstractSequentialList类中的例子解释上面抽象的描述。
该类中有一个get方法,其具体实现如下

public E get(int index) {
	ListInterator<E> i = listIterator(index);
	try {
		return i.next();
	} catch (NoSuchElementException e) {
		throw new IndexOutOfBoundsException("Index: " + index);
	}
}

上述代码接收一个int型的参数index,返回集合中下标为index的元素。值得注意的是,该函数要求index的值大于等于0,但小于集合中元素的总数。

next()方法的抛出一个NoSuchElementException异常,倘若不使用异常转译,调用get方法的客户端将直接得到一个NoSuchElementException的异常,这样会使得客户端对异常产生的原因感到迷惑。通过异常转译,使用try-catch捕获一个NoSuchElementException异常并将其转换为IndexOutOfBoudsException异常,调用get方法的客户端看见这个异常,便能很快知道是由于参数index超出了规定的范围而导致的该异常,一目了然。

一种更加推荐的做法

在上述代码中,抛出的IndexOutOfBoundsException异常只包含index的信息,一种更加推荐的做法是:

调用构造函数IndexOutOfBoundsException(Throwable cause),将低层的NoSuchElementException异常传入高层异常IndexOutOfBoundsException。当客户端调用get方法同时得到一个IndexOutOfBoundsException时,可以调用ThrowablegetCause方法得到低层的异常NoSuchElementException。这种保留低层异常的方式能够为客户端提供更多的关于异常的信息,方便客户端找到异常产生的原因。

值得注意的一点

通常我们只使用try-catch捕获受查异常,但是在异常转译中,我们使用try-catch捕获并转译的异常却没有这个限制,只要拥有足够的理由对某个异常进行转译,那么即使是RuntimeException,也是可以使用try-catch去捕获并转译的。
(上述例子中转译的NoSuchElementException就是一个RuntimeException.)

参考资料

《Effective Java》第三版

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值