2011-07-21 72 views
7

在我採訪的一個,他們問我,是有可能寫在捕獲Throwable()這樣的是catch塊能趕上的Throwable(錯誤和異常)

try{ 
some code 
} 
catch(Throwable t) 
{ 
} 

我說是的。它不會給編譯時錯誤,但如果發生Error(Throwable的子類),jvm將不會處理它,因爲錯誤是不可處理的不可逆條件,無法由jvm處理。比他們進一步詢問寫Throwable有什麼用處。

請給我適當的答覆,我們可以使用Throwable in catch。如果是的話。

+4

我使用這種問題作爲一種方法來清除我不想工作的地方,或者是因爲現有的代碼必須太棘手,或者管理員過於執着於他們知道他們下屬使用的編程語言的一些瑣事,或者更糟糕的東西... –

回答

10

有可能趕上Throwable。是的,你也會遇到java.lang.Error的例子,這是一個問題,例如, OutOfMemoryError's。一般來說,我不會趕上Throwable的。如果必須,您應該在呼叫堆棧的最高位置執行操作,例如main方法(您可能想要抓住它,記錄它並重新拋出它)。

我同意你的論證,捕捉你無法處理的事件(例如OutOfMemoryError)是沒有意義的。一篇不錯的文章是here

+0

但是輸出是什麼。該程序是否真的處理了OutOfMemoryError或jvm仍然會停止 – Romi

+2

@romi - 爲什麼不寫一個測試程序並找出?針對各種JVM運行測試,然後當你問下一個問題時,真的會讓面試官失望! –

+0

@Romi - * output *表示OutOfMemoryError(或任何其他Throwable)將被捕獲,中斷try塊中的實際進程,然後被忽略(因爲catch塊爲空)。但是由於缺乏記憶,進一步處理不可能奏效。 –

0

Throwable可以用來代替任何單獨的異常/錯誤。不過建議通過ThreadDeadException。所以你可以爲它添加額外的catch子句,或者按類型過濾。

+0

1)它被稱爲'ThreadDeath'而不是'ThreadDeadException'。 2)如果您使用長期棄用的Thread.destroy()方法,您將只能看到它。不要這樣做。 3)其實,建議你不要捕捉任何'Error'異常;即'java.lang.Error'及其所有子類。 –

2

是的,有可能趕上Throwable

如果發現錯誤,JVM /應用程序是否能夠繼續運行取決於發生的實際錯誤,導致錯誤的原因以及應用程序接下來執行什麼操作(如果有的話)。

  • 在某些情況下,JVM可能如此糟糕,無法恢復。

  • 在某些情況下,JVM很好......只要你不做某些事情。類加載錯誤就是一個很好的例子。如果您的應用程序不嘗試使用您未能加載的類或相關類,則應該可以繼續。 (實際上,應用程序不會被設計爲沒有未加載的類繼續......但如果是的話,它可以)。

  • 在某些情況下,核心JVM將會正常,但未指定的損壞可能是完成應用程序的數據結構,和/或其線程和計算狀態。 OOME可能會對你這樣做,特別是如果你的應用程序不是用來處理意外死亡的線程的話。

  • 由於另一個原因,從OOME捕捉和恢復是有問題的。儘管當前計算的終止將釋放一些堆空間,但很有可能它不會釋放足夠的空間。因此,您可以輕鬆進入應用程序反覆拋出並捕獲大量OOME的情況,並且沒有取得真正的進展。

所有這一切意味着嘗試從錯誤中恢復通常是一個壞主意。而這與什麼錯誤的Javadoc說行:

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

0

捕獲Throwable將捕獲所有異常(包括RuntimeExceptions)和所有錯誤。不建議捕獲任何父Throwables(Throwable,Error,Exception或RuntimeException),但如果方法拋出過多檢查異常或拋出Exception,則發現此情況並不少見。

在某些API中將方法記錄爲拋出異常並不罕見。這以控制爲代價提供了一些靈活性。我喜歡定義一個新的Exception類來處理這種情況,但這是個人偏好。

以下簡單類顯示了可拋出類型和相應的catch塊的示例。

public class ThrowableExamples { 

    public static void main(String[] args) { 
     try { 
//   throw new NoSuchMethodException("Exception"); 
//   throw new Exception("Exception"); 
//   throw new IllegalStateException("RuntimeException"); 
//   throw new RuntimeException("RuntimeException"); 
      throw new NoSuchMethodError("Error"); 
//   throw new Error("Error"); 
//   throw new Throwable("Throwable"); 

     } catch (RuntimeException e) { 
      System.out.println("Caught RuntimeException: " + (e.getMessage().equals("RuntimeException") ? "Expected" : "Unexpected")); 

     } catch (Exception e) { 
      System.out.println("Caught Exception: " + (e.getMessage().equals("Exception") ? "Expected" : "Unexpected")); 

     } catch (Error e) { 
      System.out.println("Caught Error: " + (e.getMessage().equals("Error") ? "Expected" : "Unexpected")); 

     } catch (Throwable e) { 
      System.out.println("Caught Throwable: " + (e.getMessage().equals("Throwable") ? "Expected" : "Unexpected")); 
     } 
    } 
}