Java异常转译(exception translation)的使用
什么是異常轉(zhuǎn)譯(exception translation)
在Java中,我們通常使用try-catch語(yǔ)句捕獲異常,進(jìn)行異常處理。但有些時(shí)候,我們使用try-catch捕獲一個(gè)異常,但卻不進(jìn)行異常處理,反而是拋出另一個(gè)異常,這就稱為異常轉(zhuǎn)譯。如下所示,
try {Method(); //某個(gè)會(huì)拋出Exception1異常的函數(shù) } catch (Exception1 e) {throw new Exception2(); }從上述代碼我們很容易理解異常轉(zhuǎn)譯這個(gè)名字的內(nèi)涵——將異常Exception1轉(zhuǎn)譯為Exception2。
為什么要進(jìn)行異常轉(zhuǎn)譯
第一次看見這樣的代碼可能會(huì)產(chǎn)生疑惑——使用try-catch語(yǔ)句通常是用來(lái)捕獲異常并進(jìn)行處理,但上述代碼卻在捕獲異常后又拋出了另一個(gè)異常,既然終究會(huì)拋出一個(gè)異常,那么何必再多此一舉使用try-catch呢?直接拋出Exception1不好嗎?
這樣做的原因是,在某些時(shí)候,高層實(shí)現(xiàn)和低層異常之間的關(guān)系不明顯,直接拋出低層異常會(huì)使調(diào)用高層實(shí)現(xiàn)的客戶端看到異常時(shí)不知所措。
下面用JDK的AbstractSequentialList類中的例子解釋上面抽象的描述。
該類中有一個(gè)get方法,其具體實(shí)現(xiàn)如下
上述代碼接收一個(gè)int型的參數(shù)index,返回集合中下標(biāo)為index的元素。值得注意的是,該函數(shù)要求index的值大于等于0,但小于集合中元素的總數(shù)。
next()方法的拋出一個(gè)NoSuchElementException異常,倘若不使用異常轉(zhuǎn)譯,調(diào)用get方法的客戶端將直接得到一個(gè)NoSuchElementException的異常,這樣會(huì)使得客戶端對(duì)異常產(chǎn)生的原因感到迷惑。通過(guò)異常轉(zhuǎn)譯,使用try-catch捕獲一個(gè)NoSuchElementException異常并將其轉(zhuǎn)換為IndexOutOfBoudsException異常,調(diào)用get方法的客戶端看見這個(gè)異常,便能很快知道是由于參數(shù)index超出了規(guī)定的范圍而導(dǎo)致的該異常,一目了然。
一種更加推薦的做法
在上述代碼中,拋出的IndexOutOfBoundsException異常只包含index的信息,一種更加推薦的做法是:
調(diào)用構(gòu)造函數(shù)IndexOutOfBoundsException(Throwable cause),將低層的NoSuchElementException異常傳入高層異常IndexOutOfBoundsException。當(dāng)客戶端調(diào)用get方法同時(shí)得到一個(gè)IndexOutOfBoundsException時(shí),可以調(diào)用Throwable的getCause方法得到低層的異常NoSuchElementException。這種保留低層異常的方式能夠?yàn)榭蛻舳颂峁└嗟年P(guān)于異常的信息,方便客戶端找到異常產(chǎn)生的原因。
值得注意的一點(diǎn)
通常我們只使用try-catch捕獲受查異常,但是在異常轉(zhuǎn)譯中,我們使用try-catch捕獲并轉(zhuǎn)譯的異常卻沒(méi)有這個(gè)限制,只要擁有足夠的理由對(duì)某個(gè)異常進(jìn)行轉(zhuǎn)譯,那么即使是RuntimeException,也是可以使用try-catch去捕獲并轉(zhuǎn)譯的。
(上述例子中轉(zhuǎn)譯的NoSuchElementException就是一個(gè)RuntimeException.)
參考資料
《Effective Java》第三版
總結(jié)
以上是生活随笔為你收集整理的Java异常转译(exception translation)的使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 云队友丨刘润:拼命成长,才不浪费一场危机
- 下一篇: cleanmymac x免费版安装包下载