2011-05-12 65 views
0

在試圖重構一些我的代碼我試圖拋出異常的catch子句中像這樣 -爲什麼嘗試/趕上可拋棄?

try { 
.... 
} 
catch(Exception exception){ 
..... 
throw exception 
} 

然而,當我試圖扔上線「拋出異常」異常的編譯器的消息抱怨我需要我的周圍扔子句中一個新的try/catch像這樣 -

try 
{ 
    .... 
} 
catch (Exception exception) 
{ 
    ..... 
    try 
    { 
    throw exception 
    } 
    catch (Exception e2) 
    { 
    ... 
    } 
} 

爲什麼編譯器需要這一點,它提供了有什麼用?

謝謝

+0

感謝所有的答案,代碼是一個線程,所以我不的run方法中認爲我可以拋出異常? – 2011-05-12 22:41:31

+0

[Throw error to calling method!]可能的重複(http://stackoverflow.com/questions/5976764/throw-error-to-calling-method) – McDowell 2011-05-12 22:50:35

+0

我不這麼認爲,但也許我錯了,我真的想知道的是爲什麼我需要圍繞「拋出異常」與try catch。拋出異常時,拋出異常不能拋出異常嗎?嘗試 { 拋出異常 } 趕上(例外E2) { ... } – 2011-05-12 22:57:35

回答

0

我的猜測是,你試圖拋出一個異常的子類,而不是由該方法聲明作爲它可以拋出的異常類型。

以下示例適用

package test.example; 

public class ExceptionTest { 

    public static void main(String[] args) throws Exception{ 
     try { 
      int value = 1/0; 
     } catch (Exception e) { 
      System.out.println("woops the world is going to end"); 
      throw e; 
     } 

    } 

} 

然而這個例子會給出一個錯誤。在第二個例子中,我簡單地捕捉異常不是RuntimeException的

package test.example; 

public class ExceptionTest { 

    public static void main(String[] args) throws RuntimeException{ 
     try { 
      int value = 1/0; 
     } catch (Exception e) { 
      System.out.println("woops the world is going to end"); 
      throw e; 
     } 

    } 

} 

注意,它不會編譯,因爲我拋出的異常是一個未聲明的拋出,即使我做申報的RuntimeException。

是的異常是一個RuntimeException,但編譯器不知道。

只是想到了第三個工作實例來向你展示。這一個也適用,因爲你拋出相同的類型,你聲明。 (注意,唯一的變化是catch塊)

package test.example; 

public class ExceptionTest { 

    public static void main(String[] args) throws RuntimeException{ 
     try { 
      int value = 1/0; 
     } catch (RuntimeException e) { 
      System.out.println("woops the world is going to end"); 
      throw e; 
     } 

    } 

} 

您需要了解所有這三個答案之間的差異

1

在您的原始代碼中,沒有任何東西能夠捕獲拋出的異常。我想你要麼指定你的函數拋出一個異常,要麼有另一個try/catch塊,因爲編譯器建議去捕捉它。

而不是

public void yourFunction(){ 
    try { 
    .... 
    } 
    catch(Exception exception){ 
    ..... 
    throw exception 
    } 
} 

嘗試

public void yourFunction() throws Exception{ 
    try { 
    .... 
    } 
    catch(Exception exception){ 
    ..... 
    throw exception 
    } 
} 
3

例外java.lang.Exception是經過檢查的異常。這意味着它必須在封閉方法的throws子句中聲明,或者用方法體捕獲和處理。

但是,你在做什麼在你的「固定」版本來捕獲異常,重新拋出它,然後立即再次抓住它。這沒有什麼意義。

沒有看到真正的代碼,目前尚不清楚真正的解決方案應該是什麼,但我相信這個問題是在原try { ... } catch處理程序:

  • 如果可能的話,你應該捕獲更具體在那個時候例外,所以當你重新拋出時,它被方法現有的throws列表覆蓋。

  • 或者,你可以包裝在unchecked異常異常,並拋出來代替。

  • 作爲最後的手段,你可以改變方法的簽名,包括Exception在拋出名單。但這是一個非常糟糕的主意,因爲它將問題推給了調用者......並使開發人員/讀者處於不知道預期會出現什麼異常的位置。

+0

我已經看到了用於捕捉和重新拋出有效的情況下。那些說...可能會記錄的行。他們可能是異常本身的邏輯等 – Wes 2011-05-12 22:24:55

+0

@Wes - 我正在談論的「固定」版本的代碼。我聲稱嵌套的'try catch'沒有任何意義。你可以刪除try塊並內聯catch塊,它會以較少的代碼行速度更快地完成同樣的事情。 – 2011-05-12 22:36:40

+0

無論如何,我還是喜歡你的答案。對於你所聲稱的,我只是有點困惑。請注意,這是在我看到您的編輯之前。 – Wes 2011-05-12 22:37:56

1

在Java中,在checked和unchecked異常之間存在區別。一個未經檢查的異常基本上可以在代碼的任何地方被拋出,如果它不是某個地方捕獲,它會傳播到你的應用程序的入口點,然後停止進程(通常是用一個錯誤信息和堆棧跟蹤)。經過檢查的異常是不同的:編譯器不會讓你就讓它傳播,你需要或者圍繞這可能會引發使用try-catch塊(與「拋出異常」 checked異常的任何代碼是最簡單的情況下,如果異常是一個檢查的異常類的實例),或者您必須標記包含可能通過「拋出」聲明拋出檢查異常的代碼調用的方法。如果期望的行爲是拋出未經檢查的異常,那麼您需要將該異常封裝在RuntimeException中。如果希望的行爲是保持異常檢查,那麼你需要添加一個throws聲明到你當前的方法。