優雅編程之這樣考慮異常,你就“正常”了(三十一)

開心一笑

【今天壓力特別大,一直感覺有一種無形的力量扼住了喉嚨,讓我呼吸困難,脖子后面老有風。剛去了趟醫院,醫生認真的檢查之后,告訴我:你毛衣穿反了!】

**提出問題******

項目中如何處理異常???

解決問題

勵志圖片

以下來自《Effective Java》這本書的筆記:

在這里復習下異常分類:

java中異常分為兩類:checked exception(檢查異常)和unchecked exception(未檢查異常),對于未檢查異常也叫RuntimeException(運行時異常).

對未檢查的異常(unchecked exception )的幾種處理方式:
1、捕獲
2、繼續拋出
3、不處理

對檢查的異常(checked exception,除了RuntimeException,其他的異常都是checked exception )的幾種處理方式:

1、繼續拋出,消極的方法,一直可以拋到java虛擬機來處理
2、用try...catch捕獲

注意,對于受檢異常必須處理,或者必須捕獲或者必須拋出

例如:

1)非受檢的:NullPointerException,ClassCastException,ArrayIndexsOutOfBoundsException,
ArithmeticException(算術異常,除0溢出)

2)受檢:Exception,FileNotFoundException,IOException,SQLException.
只針對異常的情況才使用異常

異常應該只用于異常情況下,它們永遠不應該用于正常控制流中。

錯誤案例:

try{
    int i = 0;
    while(true){
        range[i++].climb();
        
    }
}catch(ArrayOutOfBoundsException e){
    //ArrayOutOfBoundsException 是非受檢異常,不應該捕獲,同時,也不應該
    //在正常代碼中處理這種異常    
}

改正:

for(Mountain m:range){
    m.climb();
}

錯誤案例

try {
    Iterable<Foo> i = collection.iterator();
    while (true){
        Foo foo = i.next();
    }
}catch (NoSuchElementException e){
    
}

改正:

for(Iterable<Foo> i = collection.iterator();i.hasNext();){
    Foo foo = i.next();
}
對可恢復的情況使用受檢異常,對編程錯誤使用運行時異常

標題已經說的很清楚了,下面簡單描述下:

在決定使用受檢的異常或是未受檢的異常時,主要原則是:如果期望調用者能夠適當地恢復,對于這種情況就應該使用受檢的異常。

有兩種未受檢的可拋出結構:運行時異常和錯誤,它們都是不需要也不應該被捕獲的可拋出結構。如果程序拋出未受檢的異常或者錯誤,往往就屬于不可恢復的情形,繼續執行下去有害無益。

優先使用標準的異常

專家級程序員與缺乏經驗的程序員一個最主要的區別在于,專家追求并且通常也能夠實現高度的代碼

代碼重用是值得提倡的,這是一條通用的規則,異常也不例外。

可以這么說,所有錯誤的方法調用都可以被歸結為非法參數或者非法狀態,即IllegalArgumentException 和 IllegalArgumentException

拋出與抽象相對應的異常

異常轉義:更高層的實現應該捕獲底層的異常,同時拋出可以按照高層抽象進行解釋的異常。

例如:

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

    public void uploadImageFile(String imagePath)  {

        try {
            /上傳圖片文件
        }catch(IOException e) {
           //把原始異常信息記錄到日記中(便于排錯)
            throw  new 異常構造方法();
     }
  }

異常鏈:將異常發生的原因一個傳一個串起來,即把底層的異常信息傳給上層,這樣逐層拋出.

try {
     lowLevelOp();
}catch (LowLevelException le) {

     throw (HighLevelException)
      new HighLevelException().initCause(le);

}

總而言之,如果不能阻止或者處理來自更底層的異常,一般的做法是使用異常轉譯,除非底層方法碰巧可以保證它跑車的所有異常也適合才可以將異常從底層傳播到高層。異常鏈對高層和底層異常都提供了最佳的功能;它允許拋出適當的高層異常,同時又能捕獲底層的原因進行失敗分析。

每個方法拋出的異常都要有文檔

始終要單獨地聲明受檢的異常,并且利用Javadoc的@throws標記,準確地記錄下拋出每個異常的條件。

具體可以參考這篇文章:檢查異常和未檢查異常不同之處

總而言之,要為你編寫的每個方法所能拋出的每個異常建立文檔。對于未受檢和受檢的異常,以及對于抽象的和具體的方法都一樣。要為每個受檢異常提供單獨的throws子句,不要為未受檢的異常提供throws子句。如果沒有為可以拋出的異常建立文檔,其他人就很難或者根本不可能有效地使用你的類或者接口。

在細節消息中包含能捕獲失敗的信息

為了捕獲異常,異常的細節信息應該包含所有“對該異常有貢獻”的參數和域的值。

例如:

/**
 * Constructs an <code>IndexOutOfBoundsException</code> with the
 * specified detail message.
 *
 * @param   s   the detail message.
 */
//這個是IndexOutOfBoundsException這個異常的構造器
public IndexOutOfBoundsException(String s) {
    super(s);
}    

期望:

/**
 * @param lowerBound
 * @param upperBound
 * @param index
 */
//通過改造后的異常可以包含足夠的能捕獲失敗的信息
public IndexOutOfBoundsException(int lowerBound,int upperBound,int index){
    super("Lower bound: " + lowerBound +
    ",Upper bound: " + upperBound + 
    ", Index:" + index);
    this.lowerBound = lowerBound;
    this.upperBound = upperBound;
    this.index = index;
}
努力使失敗保持原子性

失敗原子性:失敗的方法調用應該使對象保持在被調用之前的狀態。

對于可變對象上執行操作的方法,獲得失敗原子性最常見的辦法是,在執行操作之前檢查參數的有效性。這可使得在對象的狀態被修改之前,先拋出適當的異常。例如:

public Object pop(){
    //如果取消對size檢查,會導致size域保持不一致的狀態
    if(size == 0){
        throw new EmptyStackException();
    }
    Object result = elements[--size];
    elements[size] = null;//
    return result;
}

另外一種獲得失敗原子性的辦法是,調整計算處理過程的順序,使得任何可能會失敗的計算部分都在對象狀態被修改之前發生。

最后一種獲得失敗原子性的辦法是,在對象的一份臨時拷貝上執行操作,當操作完成之后,再用臨時拷貝中的結果代替對象的內容。

不要忽略異常

當API的設計者聲明一個方法將拋出某個異常的時候,他們等于正在視圖說明某些事情。所有請不要忽略它!

例如:

try{
    ...
}catch(SomeException e){
        
}

上面的例子中,是一個空的catch塊,空的catch塊會使異常達不到應有的目的,

讀書感悟

來自宗白華《美學散步》

  • 中國的建筑、園林、雕塑中都潛伏著音樂感——即所謂“韻”。西方有的美學家說:一切的藝術都趨向于音樂。這話是有部分真理的。
  • 一切藝術的美,以至于人格的美,都趨向于玉的美:內部有光澤,但是含蓄的光采,這種光彩是極絢爛又極平淡。
  • 音樂領導我們去把握世界生命萬千形象里最深的節奏的起伏。

其他

如果有帶給你一絲絲小快樂,就讓快樂繼續傳遞下去,歡迎轉載,點贊,頂,歡迎留下寶貴的意見,多謝支持!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容

  • 第五十七條、只針對異常的情況才使用異常 不要優先使用基于異常的模式:因為異常機制的設計初衷是用于不正常的情況,所以...
    Timorous閱讀 676評論 0 1
  • 通俗編程——白話JAVA異常機制 - 代碼之道,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語閱讀 3,191評論 0 25
  • 57、只針對異常的情況才使用異常 在這段代碼中,當循環企圖訪問數組邊界之外的元素時,拋出異常,以達到終止無限循環的...
    Alent閱讀 335評論 0 3
  • 57,值針對異常的情況才適用異常 在現代jvm上實現上,基于異常的模式比標準模式要慢的多。 異常只能用于異常情況下...
    求閑居士閱讀 392評論 0 0
  • 充分發揮異常的優點,可以提高程序的可讀性、可靠性和可維護性。如果使用不當,它們會帶來負面影響。 1.只針對異常的情...
    666真666閱讀 263評論 0 0