Effective java筆記(八),異常

57腰吟、只針對異常的情況才使用異常

try {
    int i = 0;
    while(true) 
        range[i++].climb();
}catch(ArrayIndexOutOfBoundsException e) {
    
}

在這段代碼中无埃,當(dāng)循環(huán)企圖訪問數(shù)組邊界之外的元素時,拋出異常毛雇,以達到終止無限循環(huán)的目的嫉称。在這個代碼片段中,基于異常的循環(huán)模式不僅模糊了代碼的意圖灵疮,而且降低了性能(異常模式比標(biāo)準(zhǔn)模式慢的多)织阅。

異常應(yīng)該只用于異常的情況,不要將它們用于控制流震捣,也不要編寫迫使客戶端使用控制流的API荔棉。

58闹炉、對可恢復(fù)的情況使用受檢異常,對編程錯誤使用運行時異常

Java語言提供了三種可拋出結(jié)構(gòu)(throwable):「受檢的異橙笥#」剩胁、「運行時異常」和「error」祥国。

  • 「受檢的異常」是程序可以處理的異常晾腔,如果拋出異常的方法本身不能處理它舌稀,那么方法的調(diào)用者就應(yīng)該去處理它,從而使程序恢復(fù)運行灼擂。例如壁查,噴墨打印機在打印文件時,如果紙用完或者墨水用完剔应,就會暫停打印睡腿,等待用戶添加打印紙或更換墨盒,如果用戶添加了打印紙或更換了墨盒峻贮,就能繼續(xù)打印席怪。

  • 「運行時異常」是程序無法恢復(fù)運行的異常纤控,導(dǎo)致這種異常的原因通常是由于執(zhí)行了錯誤操作挂捻。一旦出現(xiàn)了錯誤操作,建議終止程序并仔細的debug船万,因此Java編譯器不檢查這種異常刻撒。

  • 「error」通常是系統(tǒng)出現(xiàn)了不可控的錯誤,這個錯誤通常與程序無關(guān)耿导,一般不需要處理声怔。 運行時異常和error都是不可恢復(fù)的情形。

對于可恢復(fù)的情況舱呻,使用受檢的異常醋火;對于程序錯誤使用運行時異常。對于自定義的未受檢的拋出結(jié)構(gòu)不要繼承自Error箱吕,它應(yīng)該是RuntimeException的子類胎撇。

59、避免不必要的使用受檢的異常

過分使用受檢的異常會使API使用起來非常不便殖氏,影響API的靈活性晚树。

60、優(yōu)先使用標(biāo)準(zhǔn)異常

使用標(biāo)準(zhǔn)異常的好處有:使API更易學(xué)習(xí)和使用雅采、可讀性更強和高度的代碼重用爵憎。

常用的異常:

異常 使用場合
IllegalArgumentException 非null的參數(shù)值不正確
IllegalStateException 對于方法調(diào)用而言慨亲,對象狀態(tài)不合適
NullPointerException 參數(shù)為null
IndexOutOfBoundsException 下標(biāo)參數(shù)越界
ConcurrentModificationException 在禁止并發(fā)修改的情況下,檢測到對象的并發(fā)修改
UnsupportedOperationException 對象不支持用戶請求的方法

61宝鼓、拋出與抽象相對應(yīng)的異常

當(dāng)方法傳遞由低層方法拋出的異常時刑棵,方法所拋出的異常與它執(zhí)行的任務(wù)沒有明顯的關(guān)系,這往往使人困惑愚铡,也讓實現(xiàn)細節(jié)污染了高層的API蛉签。為了避免這個問題,更高層的實現(xiàn)應(yīng)該捕獲低層的異常沥寥,同時拋出按高層抽象進行解釋的異常碍舍。這種做法被稱為「異常轉(zhuǎn)譯」。

例如:AbstractSequentialList類中

/**
 * Returns the element at the specified position in this list.
 * 
 * @throw   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);
    }
}

如果低層的異常對于調(diào)試導(dǎo)致高層異常的問題有幫助邑雅,可以使用「異常鏈」將低層的異常傳到高層的異常中片橡,并使用高層異常的方法(Throwable.getCause)來獲取低層異常。如:

try {
    ...
} catch (LowerLevelException e) {
    throw new HigherLevelException(e);
}

總之淮野,如果不能阻止或處理來自低層的異常捧书,一般使用「異常轉(zhuǎn)譯」來保證所拋出的異常適合高層≈栊牵「異常鏈」:它允許拋出適當(dāng)?shù)母邔赢惓>桑瑫r又能捕獲底層的原因進行失敗分析。

62洞难、每個方法拋出的異常都要有文檔

要為編寫的每個方法所能拋出的每個異常建立文檔了嚎。為每個受檢異常提供單獨的throws子句,并利用@throws標(biāo)記記錄下拋出每個異常的條件廊营。不要使用throws關(guān)鍵字將未受檢的異常包含在方法的聲明中歪泳。

63、在細節(jié)消息中包含能捕獲失敗的信息

異常的字符串表示法主要是讓程序員或域服務(wù)人員來分析失敗的原因露筒,所以其應(yīng)該包含盡可能多的失敗信息呐伞,以便于分析。

為了確保在異常的細節(jié)消息中包含足夠的能捕獲失敗的信息慎式,一種做法是在異常的構(gòu)造器而不是字符串細節(jié)消息中引入這些信息伶氢。如:

/**
 * Constructs an <code>IndexOutOfBoundsException</code> with the
 * specified detail message.
 * @param  lowerBound the lowest legal index value
 * @param  upperBound the highest index value plus one
 * @param  index      the actual index value
 */
public MyIndexOutOfBoundsException(int lowerBound, int upperBound, int index) {
    super("Lower bound: " + lowerBound + ", Upper bound: " + upperBound + 
        ", Index: " + index);
}

//使用
....
throw new MyIndexOutOfBoundsException(0, 10, i);

64、努力使失敗保持原子性

一般而言瘪吏,為了能從異常中恢復(fù)癣防,失敗的方法調(diào)用應(yīng)該使對象保持在被調(diào)用之前的狀態(tài),稱這中方法具有「失敗原子性」掌眠。

對于不可變對象蕾盯,它具有失敗原子性是顯然的。因為對象的狀態(tài)始終保持一致蓝丙。

對于可變對象獲得失敗原子性最常見的方法:在執(zhí)行操作之前檢查參數(shù)的有效性级遭,這可以使對象的狀態(tài)在被修改之前望拖,先拋出適當(dāng)?shù)漠惓!H纾?/p>

public Object pop() {
    if(size == 0)
        throw new EmptyStackException();
    Object result = elements[--size];
    ....
}

總之挫鸽,產(chǎn)生任何異常都應(yīng)該讓對象保持在方法調(diào)用之前的狀態(tài)说敏。若違反了這條規(guī)則,API文檔中應(yīng)該清楚的指明對象處于什么樣的狀態(tài)丢郊。

65盔沫、不要忽略異常

用空的catch塊來忽略異常,可能會產(chǎn)生災(zāi)難性的后果枫匾。永遠也不要忽略異常架诞。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市婿牍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惩歉,老刑警劉巖等脂,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異撑蚌,居然都是意外死亡上遥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門争涌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粉楚,“玉大人,你說我怎么就攤上這事亮垫∧H恚” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵饮潦,是天一觀的道長燃异。 經(jīng)常有香客問我,道長继蜡,這世上最難降的妖魔是什么回俐? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮稀并,結(jié)果婚禮上仅颇,老公的妹妹穿的比我還像新娘。我一直安慰自己碘举,他們只是感情好忘瓦,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著引颈,像睡著了一般政冻。 火紅的嫁衣襯著肌膚如雪枚抵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天明场,我揣著相機與錄音汽摹,去河邊找鬼。 笑死苦锨,一個胖子當(dāng)著我的面吹牛逼泣,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播舟舒,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼拉庶,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了秃励?” 一聲冷哼從身側(cè)響起氏仗,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎夺鲜,沒想到半個月后皆尔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡币励,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年慷蠕,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片食呻。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡流炕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仅胞,到底是詐尸還是另有隱情每辟,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布干旧,位于F島的核電站影兽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏莱革。R本人自食惡果不足惜峻堰,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盅视。 院中可真熱鬧捐名,春花似錦、人聲如沸闹击。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贺归,卻和暖如春淆两,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拂酣。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工秋冰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人婶熬。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓剑勾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赵颅。 傳聞我的和親對象是個殘疾皇子虽另,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 第五十七條捂刺、只針對異常的情況才使用異常 不要優(yōu)先使用基于異常的模式:因為異常機制的設(shè)計初衷是用于不正常的情況,所以...
    Timorous閱讀 670評論 0 1
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評論 25 707
  • 對象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法募寨,而不是構(gòu)造函數(shù)創(chuàng)建對象:僅僅是創(chuàng)建對象的方法族展,并非Fa...
    孫小磊閱讀 1,986評論 0 3
  • 通俗編程——白話JAVA異常機制 - 代碼之道,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語閱讀 3,180評論 0 25
  • 文/雪漠 大約在初二的時候绪商,學(xué)校來了一班新生苛谷。他們上初一辅鲸,跟我們初二是一排教室格郁。每次下課,不遠的墻角處独悴,就會有幾位...
    陽焱焱閱讀 632評論 0 0