Java 異常處理學習總結

來源:互聯網
上載者:User

      Java 異常處理學習總結 ---------------------------------------------------------------------------------------

 

      1.  語言提供內建一致的錯誤處理機制,避免不一致的錯誤處理方式和風格。其基本思想是,讓錯誤源將合適的資訊傳到某個接收者進行處理;這個接收者可能與錯誤源位於同一抽象層次,更可能位於更高的抽象層次。做個簡單的類比,當員工無法處理某些問題時,就要提交到高層管理去處理。

 

      2.   Java 的異常處理文法並不多, try-catch-finally, throw, throws ,關鍵在於異常的合理使用: 何時使用異常;如何正確使用異常;當異常發生時,要確保程式處於正確穩定的狀態下。You should always ask : when exception happens , will everything properly cleanup ?

 

     3.   異常處理機制的益處: 將正確情形代碼與錯誤處理相分離。

     遵循傳統錯誤處理方式的代碼是:                                     使用異常處理的代碼是:

     if1 (! Exception1) {                                                                         try   {

              // 正確情形代碼1                                                                                    // 正確情形代碼1 ……

     }                                                                                                                         // 正確情形代碼N

     else1 {                                                                                              } catch (Exception1) {

             //  錯誤情形代碼1                                                                                  //  錯誤情形代碼1

     }                                                                                                         }

     ……                                                                                                  ……

 

     ifN (! ExceptionN) {                                                                         } catch (ExceptionN) {

              // 正確情形代碼N                                                                                 // 錯誤情形代碼N

     }                                                                                                          } finally {

     elseN {                                                                                                          // 清理資源,或使程式回複某個狀態

             //  錯誤情形代碼N                                                                    }

     }

 

     4.  自訂異常的方法很簡單,讓它繼承自Java 中的已有異常,比如 Exception . 自訂異常的一個重要事項是異常類的名字必須取好,望文生義,具有自描述性。因為,錯誤源的資訊提示是非常重要的。

 

     5.  異常的重要繼承體系: RuntimeException ---> Exception --- > Throwable , Error ---> Throwable . 其它異常均是繼承於此。異常的重要方法有: getClass().getName() [擷取異常類名];getMessage() , getLocalizedMessage() [異常資訊]; new SomeException(String), new SomeException(Throwable)[構造器]; fillInStackTrace(),
getCause() [用於重拋異常];initCause(Throwable) [異常鏈] ;printStackTrace() , printStackTrace(PrintStream) , printStackTrace(PrintWriter) [列印異常發生棧調用資訊] 。

 

     6.  Java 異常鏈: 將剛剛捕獲的異常對象作為構造器參數傳入將要拋出的異常對象,或者作為 initCause() 方法的參數傳入,可以使即將拋出的異常儲存有剛剛捕獲的異常對象的資訊,構成異常鏈,用來表達因果關係。

 

     7.  若類的方法 f 中拋出異常A1,A2,...,An,則該方法的聲明必須指定異常聲明 f() throws A1, A2, ..., An (A1, A2, ..., An 若是 RuntimeException 或其衍生類別異常,則可以不指定。)

 

     8.   異常佔位或預留技術: 方法中並不拋出異常,但方法中仍然指定該異常聲明 。這樣做的好處時,當真正需要在方法中拋出該異常時,不會影響客戶代碼;因為客戶代碼已經對該異常進行處理了(在沒有實際拋出該異常之前)。

 

     9.   異常聲明限制:

      (1) 子類構造器的異常聲明列表必須是基類構造器異常聲明列表的超集,即:若基類構造器的異常聲明列表是 {A1,A2,...,An} , 則子類構造器的異常聲明列表 S >= {A1,A2,...An} ; 這是因為,調用子類構造器之前必然調用基類構造器,因此,子類構造器必須處理基類構造器所聲明的所有異常;

     (2) 子類覆寫方法的異常聲明列表必須是基類方法異常聲明列表的子集,即:若基類方法的異常聲明列表是 {A1,A2,...,An} , 則子類覆寫方法的異常聲明列表 S <= {A1,A2,...An} ; 這是因為, 客戶代碼是基於基類方法提供的公用介面來編程的,只應當處理基類方法提供的公用介面所聲明的異常。

     (3) 子類型的介面實現方法的異常聲明列表必須是介面方法異常聲明列表的子集。這是因為,客戶代碼是基於介面方法的聲明來編程的,只應當處理介面方法提供的異常說明。

 

     10.   RuntimeException 及其衍生類別的特殊性: 

     (1) 若異常發生,則系統會自動拋出RuntimeException 或其衍生類別對象,無需程式員顯式拋出;

     (2) 若方法中拋出 RuntimeException 或其衍生類別異常,則方法的異常說明中無需指定這些異常;

     (3) 由於 RuntimeException 及其衍生類別無需程式員顯式拋出,因此,編譯器不會給予 try-catch-finally 提示; 程式員可能不會去捕獲這樣的異常,從而使這些RuntimeException 通過重重關卡逃出 Main() 而未被捕獲, 此時程式將自動調用該異常的printStackTrace,並終止程式;

     (4) RuntimeException 及其派生異常通常代表程式中的錯誤,比如 數組的 IndexOutOfBoundsException 異常;應盡量避免出現此類異常。

 

    11.  在構造器中拋出異常會導致非常棘手的問題;因此,盡量不要在構造器中拋出任何異常;盡量使構造器能夠 100%的成功運行。

 

    12.  異常匹配: 當異常發生時,系統將使用new建立一個異常對象(像建立一個普通Java對象一樣),並獲得一個引用;接著,系統將中止當前執行路徑,而轉到相應的例外處理常式中(類似中斷處理,但不會返回到原執行路徑); 匹配哪個例外處理常式按以下規則:

    (1) 通常從緊隨其後的一系列 catch 語句進行搜尋;搜尋順序是按catch語句出現的先後順序;一旦匹配成功,就不再匹配後面的catch語句了;

   (2) 匹配的準則是: catch (B) 將捕獲一切 B 及其衍生類別對象 (遵循多態機制) ;反之, 若拋出 A, 則可以由 A 的一切父類對象來捕獲。先來先得。

   (3) 異常屏蔽: 若拋出B對象,且 B ---> B1 ---> B2 ---> ... ---> Bn, --->表示繼承關係,則在該繼承層次上,越靠近B(更精準匹配),其catch 語句的順序越應放在前面(如果同時出現的話),即 catch 語句塊的順序應該依次是 catch(B1),catch(B2), ..., catch(Bn)。比如 RuntimeException 應置於 Exception 之前,因為 Exception 可以捕獲一切異常,這就是說,若順序是:... catch(Exception
e ) { // } catch (RuntimeException e) { } , RuntimeException 將沒有執行的機會。

 

   13. 異常使用準則: 避免立即捕獲和處理異常,而是將它交由合適的層次進行處理。因為錯誤處理的抉擇可能涉及到系統整體的設計,而不是局部的問題。這類似於公司的客戶投訴中心:問題通常不一定是由最底層人員的接收者來處理,而是一層層提交給更合適的某個管理層進行處理。

 

   14. 受檢異常及其處理方法: 通俗地說, 非 RuntimeException 異常都是受檢異常,它在編譯時間被檢查出來,必須立即進行處理:要麼 提交給更高層,要麼立即在緊隨其後的catch 語句進行處理。 受檢異常帶來的麻煩是,有時,你並沒有足夠的資訊來進行決策和處理(必須提交到更高層),或者根本不想進行處理(試想你調用某個人的方法,該方法拋出異常,而你會覺得這似乎不關自己的事情)。

       受檢異常有兩種處理方法: 傳遞到控制台,main() throws XXXException ; 或者將其封裝成 RuntimeException 。採用後者,你並不會丟棄異常(not to be silently swallowed),方法中也不必指定異常說明,並且,產生的異常仍然被保留下來。但在某個地方,你仍然需要去處理它。

 

    15.  錯誤處理的思考: 最理想的錯誤處理應該是怎樣的呢? 程式中應織有一張恢恢疏而不露的天網,程式中的所有錯誤都能夠被捕獲,並在合適的地方得到處理。結合 Java 的異常處理機制: A. 在可能出現錯誤的地方拋出異常,避免立即進行處理(除非有足夠資訊能夠確知如何進行處理); B. 當捕獲到異常時,如果確知如何處理,用catch塊進行處理;否則,應該將其封裝並重新拋出,提交給更高層進行處理。

 

    16.  《Thinking In Java》: 語言可以提供一些好的特性供程式員運用,但最終的使用權在程式員手上。 A good language should help programmers program well , but no languge could prevent programmers from bad practice. 學習一門語言,不僅僅是掌握其文法和用法,更要領悟其設計思想,避開語言設計的不足和陷阱,使用語言的優良特性編寫可靠、可維護的系統。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.