簡體   English   中英

Java未經檢查/檢查異常澄清

[英]Java unchecked/checked exception clarification

我一直在閱讀關於未經檢查和已檢查的問題,沒有一個在線資源真正清楚這些差異以及何時使用兩者。

根據我的理解,它們都會在運行時拋出,它們都代表超出邏輯預期范圍的程序狀態,但必須明確捕獲已檢查的異常,而未經檢查的異常則不會。

我的問題是,假設為了論證我有一個方法來划分兩個數字

double divide(double numerator, double denominator)
{    return numerator / denominator;    }

和某個需要divison的方法

void foo()
{    double a = divide(b, c);    }

誰負責檢查分母為零的情況,是否應檢查或取消檢查異常(忽略Java內置的分區檢查)?

那么,除法方法是按原樣還是按原樣聲明

double divide(double numerator, double denominator) throws DivideByZeroException
{
    if(denominator == 0) throw DivideByZeroException
    else ...
}

void foo()
{
    try{
        double a = divide(b, c);
    }
    catch(DivideByZeroException e)
    {}
}

或者沒有經過檢查的例外,原樣如下:

double divide(double numerator, double denominator)
{
    if(denominator == 0) throw DivideByZeroException
    else ...
}

void foo()
{
    if(c != 0)
       double a = divide(b, c);
}

並允許foo通過零檢查進行除法?

這個問題最初出現在我寫的數學程序中,用戶輸入的數字和邏輯類執行計算。 我不知道GUI是否應該立即檢查不正確的值,或者內部邏輯是否應該在計算期間捕獲它們並拋出異常。

有趣的話題確實!

在閱讀並嘗試了很多方法來處理一般錯誤和異常后,我學會了程序員錯誤預期錯誤之間的區別。

程序員錯誤永遠不應該被捕獲,而是早期和困難地崩潰(!)。 程序員錯誤是由邏輯錯誤引起的,應該修復根本原因。

應始終捕獲預期的錯誤 此外,當捕獲到預期錯誤時,必須為用戶顯示一條消息。 這有一個重要的含義 - 如果預期的錯誤不應該顯示錯誤,最好檢查方法是否會拋出而不是讓它拋出。

所以應用到你的例子我會想“這應該如何看待用戶?”

  1. 如果應該顯示錯誤消息(在瀏覽器輸出,控制台,消息框中),我會拋出一個異常並盡可能接近UI並輸出錯誤消息。
  2. 如果不顯示錯誤消息,我會檢查輸入而不是拋出。

旁注:我從不拋出DivideByZeroExceptionNullPointerException - 我讓JVM為我拋出這些東西。 在這種情況下,您可以釀造自己的異常類或使用合適的內置檢查異常。

我最喜歡討論Java中已檢查和未檢查異常之間的哲學差異:

http://www.javapractices.com/topic/TopicAction.do?Id=129

Java異常僅由編譯器檢查,但java設計者決定將它們分成多個類別,基本上涉及擴展的超類

  • java.lang.Exception - 稱為已檢查的異常
  • java.lang.RuntimeException稱為UNchecked異常 - 作為獎勵java.land.RuntimeException擴展java.lang.Exception(以簡化catch塊中的處理,而不僅僅是)
  • java.lang.Error - 錯誤,也是未經檢查的,很少需要由用戶空間代碼處理,但知道它們及其差異是一個主要的優點。 它們包括(最着名的):鏈接錯誤,堆棧溢出,內存不足,斷言錯誤
  • java.lang.Throwable - 經過檢查! 所有例外的母親,很少需要直接將其子類化,但有些是出於未知原因

因此,需要聲明異常並處理正確的傳播(僅在編譯級別),未經檢查的那些是自動傳播的,並且除非需要,否則不期望開發人員提供處理。

通常預期會檢查一些,並且需要在java中已經非常冗長的代碼。

最糟糕的做法包括: catch (Throwable t){} ,由於很多原因,除非必要,否則通常不會處理錯誤,並且大多數錯誤通常會導致線程死亡。

假設由於數學運算而拋出了已檢查的異常。 除法(根據你的帖子)。
這意味着每個整數除法應出現在try塊中!
實際上,division可以拋出一個ArithmeticException,它是未經檢查的異常,所以不需要捕獲它。
實際上你不應該抓住它,因為它是一種特殊情況,通常只能通過代碼校正來解決。
在您的情況下,您的代碼應該實際除以零之前完成某些操作。
如果你已經達到允許實際除零的步驟,那么你無能為力。 該程序是錯誤的,最好修復,而不是嘗試以某種方式通過拋出/捕獲異常來偽裝它

簡短的回答,因為一些優點和缺點被命名:這是個人或組織風格的問題。 沒有一個在功能上優於另一個。 您(或您的項目)必須自行決定是使用已檢查或未檢查的異常,還是兩者都有。

Oracle的Java Tutorial建議您對應用程序可以從中恢復的所有錯誤使用已檢查的異常,並為應用程序無法從中恢復的錯誤取消選中異常。 但根據我的經驗,大多數應用程序可能會從大多數(可能不在啟動期間)異常中恢 失敗的操作將被中止但應用程序仍然存在。

我寧願只使用已檢查的異常或未經檢查的異常。 混合可能導致混淆和使用不一致。 務實。 在你的情況下做有意義的事情。

永遠不要顯式拋出RuntimeException 如果您認為您需要讓運行時執行此操作而不是使用throw

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM