2010-12-10 70 views
1

異常處理是將應用程序從崩潰中最有用的機制。即使我們大多數人遵循異常處理機制。即使我看到許多仍然得到例外。我們是否應該以某種方式處理例外情況?我的問題是,處理任何異常的最佳方式是什麼?如何有效處理任何類型的異常?

我想澄清一些事情。當我說處理異常時,不僅意味着捕獲適當的異常消息並顯示或記錄它。相反,它假定處理例外的糾正措施。

讓我們考慮這段代碼:

try { 
    someMethod1(); 
} catch (MyException e) { 
    System.out.println(e.getMessage()); 
} catch (YourException e) { 
    System.out.println(e.getMessage()); 
} 

在上面的代碼,「MyException」和「YourException」可能無法捕捉所有類型的異常。但是,我們當然可以使用「java.lang.Exception」。我們如何識別正確的異常類型?以及如何處理該異常?特別是在使用外部庫時。

根據要求更詳細。

謝謝

+0

危險的問題! – Yehonatan 2010-12-10 08:37:49

回答

7

您不想捕獲運行時異常。原因是,你只是在那裏隱藏了一個bug。而是讓應用程序失敗並修復它。要回答你的問題,如果你抓住Throwable,你將基本吃掉任何一種例外。

經驗法則:只捕獲應用程序異常。

+3

我大多數人都同意,但我認爲這條規則應該是「只知道你知道要處理的例外情況」。有一些RuntimeExceptions可以用來捕獲(特別是因爲許多庫正在拋出檢查異常 - 例如JPA)。甚至有可能處理的奇怪的'錯誤'。 – gustafc 2010-12-10 09:16:10

-1

您的代碼是正確的。如果someMethod1()方法未聲明任何其他異常,則它們是RuntimeExceptions,並且您應該捕獲RuntimeException

+0

它是否滿足任何類型的異常? – 2010-12-10 08:19:33

4

我不知道我是否真的開始你問題的意思,但是,因爲你需要在代碼的某一塊,你可以捕捉儘可能多的expceptions:

try { 
    someMethod1(); 
} catch (MyException e) { 
    System.out.println(e.getMessage()); 
} catch (YourException e) { 
    System.out.println(e.getMessage()); 
} catch (IOException e) { 
    //handle 
} catch (SQLException e) { 
    //handle 
} 

,並根據異常層次結構,當你捕獲一個異常時,你也捕獲這個異常的每個子類型,所以,當你需要捕獲每個意外錯誤時,你可以爲java.lang.Exception添加一個catch(在最後的catch語句)

try { 
    someMethod1(); 
} catch (MyException e) { 
    System.out.println(e.getMessage()); 
} catch (YourException e) { 
    System.out.println(e.getMessage()); 
} catch (Exception e) { 
    //handle generic unexpected exception 
} 

你也可以捕捉超級界面Throwab le,但不推薦,因爲唯一的區別是,除了例外情況外,你也會發現錯誤。這些錯誤是致命的條件,不應該處理,因爲它們用來表示Java VM中的嚴重問題,如內存不足,堆棧溢出等。

這些鏈接對於如何處理Java異常很有用:

問候。

1

如果你真的想抓住每一個可能的例外,趕上Throwable是你想要做什麼:

try { 
    somethingThatMayFail(); 
} catch (Throwable t) { 
    t.printStackTrace(); 
} 

往往不是,這是一個壞主意,但。 如果你不知道它們爲什麼發生,或者如何清理它們,你不應該捕捉任何異常。沒有崩潰並不一定是好事 - 如果你的程序被破壞,崩潰是負責任的事情。考慮一下這個方法:

public Thing loadThing(long id){ 
    try { 
     return doLoad(id); 
    } catch (Throwable t) { 
     // What do we do here? 
    } 
} 

編譯器迫使你返回或拋出從方法的每一個可能的執行路徑的東西,但只有非特殊路徑讓我們返回的東西明智的。我們可以從catch子句返回null,但是調用代碼可能會忘記檢查返回值爲null,這意味着您最終會得到一個NullPointerException,這更難破譯,因爲它不會告訴您什麼真正的錯誤是或發生在何處。

例外情況良好。每種明智的語言都有它們的原因。

0

這聽起來像是你想弄清楚如何知道你什麼時候處理了每一個可能的異常。如果你只是沒有在你的方法上放置一個throws子句,那麼編譯器會告訴你哪些異常需要放置處理程序。

1

可以通過反射檢查任何物體的類型。但我不喜歡使用它。

try { 
    throw new Exception1(); 
} catch (Throwable t) { 
    // just get name 
    System.out.println(t.getClass().getName() + " caught"); 

    // or try instanceof - this is not nice approach IMO 
    if (t instanceof Exception1) { 
     System.out.println("yes exception1"); 
    } 
} 

BTW是否認爲或聽說過AOP?更精確地講一下AspectJ。面向方面的編程可以回答您的問題,即如何在您的代碼仍然乾淨且易於維護時打印或記錄異常。如果您正在使用Java EE和EJB,則可以嘗試使用攔截器機制而不是AspectJ。我建議你閱讀一些關於AOP和AspectJ(用於Java)的內容。

歡呼

0

如果您使用的是Eclipse,一種方式是寫出來與異常處理的代碼,它會讓你看到的類型,你的代碼可能會拋出異常。 如果您希望您的程序序列繼續編碼,那麼您只能圍繞那些可能拋出異常並在Catch塊中執行必要步驟的代碼部分,以便您的程序在所需流程中工作。

「 代碼...

嘗試{ 東西.... }趕上(someException E){// 處理它 }

嘗試{ 東西...... } catch(someException e){ //處理它 }

代碼... 「

但是,此代碼不會捕獲任何可能發生的異常(即,不是因爲您的代碼)。對於一個外嘗試捕捉可能會幫助你發現它是別的東西

「 嘗試 { 代碼...

嘗試{ 東西.... }趕上(someException E){// 處理它 }

嘗試{ 東西.... }趕上(someException E){ //處理它 }

代碼... } 趕上(運行時五){// 告訴用戶/日誌意想不到的事情已發生 } 「