JavaRush /Java Blog /Random-TW /異常處理中的常見錯誤
Ve4niY
等級 14

異常處理中的常見錯誤

在 Random-TW 群組發布
異常是對 Java(或任何其他)程式的正常執行流程的中斷。這種違規可能是由於記憶體存取違規、除以零、初始化問題、執行非法指令或任何其他致命錯誤而發生的。Java 能夠優雅地處理所有這些不需要的場景,但是當開發人員使用這些 Java 功能時,可能會出現一些問題。在本文中,我不打算討論Java中的異常處理如何運作。我假設讀者已經熟悉異常層次結構、檢查異常非檢查異常和運行時異常。在這裡,我們將討論您應該避免的最常見錯誤。
例外的利害關係人
每當執行緒被中斷時,有關它的資訊必須傳回給程式執行器。該執行緒可以從螢幕、批次任務或任何其他方式啟動。所有這些觸發器都會等待流中出現某種違規情況,以傳輸某種格式的訊息。基於螢幕的觸發器可以溫和地讓我們知道存在一些技術問題,我們應該聯繫支援人員尋求協助和建議。批次或獨立 Java 程式可能期望錯誤報告以最終使用者完全無法理解的某種日誌形式出現。但商務人士需要以他們理解的語言接收訊息。使用者心目中可怕的NullPointerException非常煩人。有時這些錯誤是由於程式使用不當造成的,但有時它們是需要糾正的問題。第二個重要的利害關係人是必須處理異常引起的問題的人。這個人無法觀察異常發生時程序的實際執行情況。它將依賴兩件事 - 首先,有問題的用戶提供的信息,第二,發生異常時生成的某種日誌。另外,分析問題的人與編寫程式的人不是同一個人,因此程式開發人員必須提供足夠的資訊來進行分析。程式開發人員與其調試人員之間通訊的唯一方式是日誌。另外,有時出於安全原因,日誌日誌有時可能不包含異常發生時程式執行的所有實際細節。讓我們看看異常處理中可能出現的錯誤。有些人看起來很傻,但確實有人。誰不注意它們,直到這些錯誤導致問題。
空異常塊
這是異常處理中最不希望出現的錯誤之一。在這種情況下,異常將被簡單地忽略。此解決方案只包含一條註解行以留下異常。 try{ }catch(SQLException sqe){ // do nothing } 在某些罕見情況下,例如在資料庫關閉時的最後一個區塊中,可能會引發異常。在這種情況下,它們可以被忽略。 try{ }catch(SQLException sqe){ ... ... }finally{ try{ conn.close(); }catch(Exception e){ //leave it. } }
異常訊息的概括不正確
這一點是主觀的。捕獲異常後,您可以以友好訊息的形式將其報告給最終用戶。當原始訊息轉換為一則通用訊息時,很可能會遺失原始訊息的細節。該訊息應向最終用戶傳達正確的訊息,以便在聯繫支援團隊時,用戶只需登入適當的日誌即可提供資訊。 try{ File file = new File(""); file.getCanonicalPath(); }catch(IOException ioe){ throw new Exception("File Processing Failed",ioe); } 在多層應用程式中,每一層都會捕獲異常並引發新類型的異常。有時絕對有必要強制轉換某種類型的異常: - 資料存取層 -> 建立 DataAccessException - 業務實作層 -> 建立 BusinessException - 應用程式服務層 -> 建立 ApplicationServiceException 一切看起來都很合乎邏輯,不是嗎?這裡我們可能必須在 ApplicationServiceException 和 BusinessException 之間進行選擇,因為兩者可以表示相同的資訊。這些異常轉換之一似乎是不必要的。
銷毀 StackTrace 類
在將異常轉換為新的特殊類型的過程中,堆疊追蹤可能會消失,從而使追蹤異常的實際原因成為一場噩夢。在下面的程式碼中,您可以看到如何在不接收原始異常的任何資訊的情況下引發新異常。 try{ File file = new File(""); file.getCanonicalPath(); }catch(IOException ioe){ throw new MyException("Problem in data reading."); }
覆蓋異常原因
每個異常訊息都包含有關異常原因的資訊。但是,當建立新的例外時,有關舊例外的資訊可能會永久刪除。這與上面的範例類似,其中 StackTrace 可能會因為拋出新異常而被刪除。
不搜尋特定異常
有時,開發人員在處理異常時喜歡謹慎行事。有時這很容易做到。但是捕獲 java.lang.Exception 而不是特定的異常是不可接受的。 try{ File file = new File(""); file.getCanonicalPath(); }catch(Exception exe){ throw new MyException("Problem in data reading."); }
不必要的接球和投擲
如果您想將異常轉換為另一種類型,或者如果它可以幫助您向最終用戶或分析人員提供的異常訊息中添加一些信息,請捕獲異常。否則,只需將它們進一步扔到方法簽名中(使用 throws),而不是捕獲它們。
捕獲運行時異常
我建議避免捕獲 RuntimeException。相反,最好捕獲特定的異常並對其進行處理。
尋找未經檢查的異常
是否捕獲未檢查的異常是一個有爭議的話題。NullPointerException 和 ArrayIndexOutOfBound 可能是未經檢查的例外狀況的最佳範例。您可以更改程式碼來處理這些情況,而不是捕獲這些異常。例如,避免 NullPointerException、確保所有變數都已初始化、避免 ArrayIndexOutOfBound 異常、定義正確長度的陣列等。
與異常日誌記錄相關的問題
該雜誌將幫助第二個有興趣的人,也就是分析問題的人。有時,開發人員過度使用日誌文件,並在應用程式的每個層級建立日誌。日誌應記錄異常發生的等級。似乎最佳的做法是顯示發生異常的警告,建議停止或繼續執行程序,並在日誌中強制記錄異常。
流控異常
異常是對程式正常流程的中斷,這表示您需要中斷此流程並通知最終使用者。如果我們添加一個作為備用線程的方法調用,將會導致巨大的維護問題。 try{ myObject.getValue(); }catch(NullPointerException npe){ alternateMethod(); }
java.lang.Exception 的普遍使用
對於任何異常,到處使用 java.lang.Exception 也不是一個好主意。相反,最好使用特定於應用程式的異常,或最合適的標準 Java 異常。 原文:異常處理中的常見錯誤 翻譯與配音:Ve4niY
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION