1.15 异常处理规则
前面介紹了使用異常處理的優勢、便捷之處,本節將進一步從程序性能優化、結構優化的角度給出異常處理的一般規則。成功的異常處理應該實現如下 4 個目標。
下面介紹達到這種效果的基本準則。
不要過度使用異常
不可否認,Java 的異常機制確實方便,但濫用異常機制也會帶來一些負面影響。過度使用異常主要有以下兩個方面:
熟悉了異常使用方法后,程序員可能不再愿意編寫煩瑣的錯誤處理代碼,而是簡單地拋出異常。實際上這樣做是不對的,對于完全已知和普通的錯誤,應該編寫處理這種錯誤處理代碼,增加程序的健壯性;只有對外部的、不能確定和預知的運行時錯誤才使用異常。
下面我們來看《Java五子棋游戲》一節中處理用戶輸入坐標點已有棋子的兩種方式。
// 如果用戶試圖下棋的坐標點已有棋子了 if (!gb.board[xPos - 1][yPos - 1].equals("╋")){System.out.println ("您輸入的坐標點已有棋子了,請重新輸入");continue; }上面這種處理方式檢測到用戶試圖下棋的坐標點已經有棋子了,立即打印一條提示語句,并重新開始下一次循環。這種處理方式簡潔明了,邏輯清晰,提高運行效率。
如果將上面的處理機制改為如下方式:
// 如果用戶試圖下棋的坐標點己經有棋子了,程序自行拋出異常 if (!gb.board[xPos - 1][yPos - 1].equals ("╋")) {throw new Exception ("您試圖下棋的坐標點已經有棋子了"); }上面的處理方式沒有提供有效的錯誤處理代碼,當程序檢測到用戶試圖下棋的坐標點已經有棋子時,并沒有提供相應的處理,而是簡單的拋出了一個異常。這種處理方式雖然簡單,但 Java 運行時接收到這個異常后,還需要進行相應的 catch 塊來捕獲該異常,所以運行效率要差一些。而且用戶下棋重復這個錯誤完全是預料的,所以程序完全可以針對該錯誤提供相應的處理,而不是拋出異常。
異常處理機制的效率比正常的流程控制效率差,所以不要使用異常處理來代替正常的程序流程控制。例如,對于以下代碼:
// 定義一個字符串數組 String[] arr = { "Hello", "Java", "Spring" }; // 使用異常處理來遍歷arr數組的每個元素 try {int i = 0;while (true) {System.out.println(arr[i++]);} } catch (ArrayIndexOutOfBoundsException ae) { }運行上面程序確實可以實現遍歷 arr 數組元素的功能,但這種寫法可讀性較差,而且運行效率也不高。程序完全有能力避免產生 ArrayIndexOutOfBoundsException 異常,程序“故意”制造這種異常,然后使用 catch 塊去捕獲該異常,這是不應該的。將程序改為如下形式肯定要好得多。
String arr[] = {"Hello","Java","Spring"}; for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]); }異常只應該用于處理非正常的情況,不要使用異常處理來代替正常的流程控制。對于一些完全可預知,而且處理方式清楚的錯誤,程序應該提供相應的錯誤處理代碼,而不是將其籠統地稱為異常。
不要使用過于龐大的try塊
很多初學異常機制的讀者喜歡在 try 塊里放置大量的代碼,這樣看上去“很簡單“,但這種”簡單“只是一種假象,因為 try 塊里的代碼過于龐大,業務過于復雜,就會造成 try 塊中出現異常的可能性大大增加,從而導致分析異常原因的難度也大大增加。而且當 try 塊過于龐大時,就難免在 try 塊后緊跟大量的 catch 塊才可以針對不同的異常提供不同的處理邏輯。同一個 try 塊后緊跟大量的 catch 塊則需要分析它們之間的邏輯關系,反而增加了變成復雜度。
正確的做法是,把大塊的 try 塊分割成多個可能出現異常的程序段落,并把它們放在單獨的 try 塊中,從而分別捕獲并處理異常。
避免使用 Catch All 語句
所謂 Catch All 語句指的是一種異常捕獲模塊,它可以處理程序發生的所有可能異常。例如,如下代碼片段:
try {// 可能引發Checked異常的代碼 } catch (Throwsble t) {// 進行異常處理t.printStackTrace(); }不可否認,每個程序員都曾經用過這種異常處理方式,但在編寫關鍵程序時就應避免使用這種異常處理方式。這種處理方式有如下兩點不足之處。
塊中使用分支語句進行控制,這是得不償失的做法。
異常等可能導致程序終止的情況全部捕獲到,從而“壓制”了異常。如果出現了一些“關鍵”異常,那么此異常也會被“靜悄悄”地忽略。
實際上,Catch All 語句不過是一種通過避免錯誤處理而加快編程進度的機制,應盡量避免在實際應用中使用這種語句。
不要忽略捕獲到的異常
不要忽略異常,既然已捕獲到異常,那 catch 塊理應處理并修復這個錯誤。catch 塊整個為空,或者僅僅打印出錯信息都是不妥的。程序出了錯誤,所有的人都看不到任何異常,但整個應用可能已經徹底壞了,這是最可怕的事情。
對異常進行合適的修復,然后繞過異常發生的地方繼續執行;或者用別的數據進行計算,以代替期望的方法返回值;或者提示用戶重新操作等。總之,對于 Checked 異常,程序應該盡量修復。
總結
以上是生活随笔為你收集整理的1.15 异常处理规则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 1.14 实例:完善除法运算的错误信息
- 下一篇: 1.2 一维数组的定义、赋值和初始化