2009-09-03 152 views
32

爲什麼Java中的某些異常未被catch (Exception ex)捕獲?這是代碼完全失敗,出現未處理的異常。 (Java版本1.4)。Java異常未捕獲

public static void main(String[] args) { 
    try { 
     //Code ... 
    } catch (Exception ex) { 
     System.err.println("Caught Exception"); 
     ex.printStackTrace(); 
     exitCode = app.FAILURE_EXIT_CODE; 
    } 
    finally { 
     app.shutdown(); 
    } 
    System.exit(exitCode); 
} 

我得到一個Exception in thread "main" java.lang.NoSuchMethodError

但這部作品

public static void main(String[] args) { 
    int exitCode = app.SUCCESS_EXIT_CODE; 
    try { 
     //Code ... 
    } catch (java.lang.NoSuchMethodError mex){ 
     System.err.println("Caught NoSuchMethodError"); 
     mex.printStackTrace(); 
     exitCode = app.FAILURE_EXIT_CODE; 
    } catch (Exception ex) { 
     System.err.println("Caught Exception"); 
     ex.printStackTrace(); 
     exitCode = app.FAILURE_EXIT_CODE; 
    } 
    finally { 
     app.shutdown(); 
    } 
    System.exit(exitCode); 
} 

我得到Caught NoSuchMethodError java.lang.NoSuchMethodError:

我想捕捉異常會捕獲所有異常?我如何捕獲java中的所有異常?

回答

99

因爲有些例外不是源自Exception - 例如ThrowableError

基本類型層次是:

 Object 
     | 
     Throwable 
    /  \ 
Exception  Error 

只有Throwables和派生類可以扔掉,所以如果趕上Throwable,真的會抓住一切。

任何異常從Exception(或Exception本身)其他比那些從RuntimeException計數推導checked異常推導 - 它們是你必須聲明你會扔,或者如果你調用的東西趕上那些拋出它們。

總而言之,Java異常層次結構是有點亂......

+6

+1:很好的圖! – akf 2009-09-03 18:31:02

+1

錯誤並不是真正的例外,因此它們不會從Exception中派生出來。 – Powerlord 2009-09-03 18:31:49

+2

@R。 Bemrose--它們根據Java語言規範:「每個異常都由Throwable類或其一個子類的實例表示」和「未檢查的異常類是RuntimeException類及其子類,以及類Error及其子類「。 – 2009-09-03 18:52:13

3

你能趕上Throwable。錯誤和例外延伸Throwable

看到的Throwable JavaDoc

的的Throwable類是Java語言中所有錯誤和異常的超類。

4

異常只是一種Throwable; NoSuchMethodError不是一個異常,而是一個錯誤,這是另一種Throwable。

0

正如其他帖子指出的那樣,catch(Exception e)只適用於從Exception派生的異常。但是,如果查看樹層次結構,則會注意到如果發生異常,則爲Throwable。 Throwable也是Error的基類。所以,在NoSuchMethodError的情況下,它是一個錯誤而不是一個例外。注意命名約定*錯誤與*異常(例如,在IOException中)。

1

正如其他海報所指出的,並非所有的可拋物體都是Exception的子類。但是,在大多數情況下,捕獲ErrorThrowable並不是一個好主意,因爲這些條件包含一些非常嚴重的錯誤條件,無法輕易從中恢復。你的恢復代碼可能會讓事情變得更糟。

+0

終於仍然會執行一個錯誤? – 2009-09-03 18:49:54

+0

是的。但是你可能會遇到更多問題。例如如果/當你遇到OutOfMemoryError時會發生什麼? – 2009-09-03 22:52:25

5

Error s不是Exception s。

的Exception類及其子類 是Throwable的一種形式,它指出 條件,合理的 應用程序想要捕獲的。

- JavaDoc for java.lang.Exception

一個錯誤是Throwable的 一個子類,表示嚴重的問題,一個 合理應用程序不應該試圖 趕上。

- JavaDoc for java.lang.Error

有一定的錯誤,你可能要趕上,如ThreadDeath。的ThreadDeath被列爲錯誤,下面

的解釋類的ThreadDeath是專門 錯誤的一個子類,而不是 例外,儘管它是一個「正常 發生」,因爲許多應用程序 捕獲所有出現異常和 然後丟棄該異常。

- JavaDoc for ThreadDeath

然而,由於線程的stop()方法現在已經過時,你不應該使用它,因此你永遠不應該看到的ThreadDeath。

+0

Java語言規範不同意你的看法:「未經檢查的異常類是RuntimeException類及其子類,以及類Error及其子類。」 – 2009-09-03 18:52:50

+0

我特別感謝沒有捕捉錯誤的建議。考慮'OutOfMemoryErrors' - 一旦拋出應用程序,它可能會處於不良狀態。捕捉並拋棄這種「錯誤」並不明智。 – akf 2009-09-03 18:53:36

+0

基本上,JLS總是指「可以拋出和抓到的東西」作爲例外。你在那裏沒有引用任何內容,表示錯誤並不是一個例外。 – 2009-09-03 18:53:54