2011-04-14 86 views
2

我是Java新手,並試圖理解Java中的異常。Java中的例外

class MyException extends Exception { 

     void someMethod() { 
      doStuff(); 
     } 

     void doStuff() throws MyException { 

     try { 
      throw new MyException(); 
      } 

      catch(MyException me) { 
      throw me; 
      } 
     } 
} 

此程序會產生錯誤:

java:3: unreported exception MyException; must be caught or declared to be thrown

doStuff(); 
     ^

try和catch塊的doStuff()方法中寫入。另外doStuff()方法「拋出」MyException,那麼爲什麼還需要在someMethod()中丟掉MyException呢?

+0

多數民衆贊成在這種情況下,你拋出異常 – 2011-04-14 01:24:01

+0

只是一個說明...檢查異常幾乎是一個Java idiosynchrasy:他們不*在OOA/OOD水平存在,並有很多語言完成很好**那個「概念」。有些人甚至認爲檢查異常是:* a)*榮耀的GOTO語句,* b)*應該被排除在語言之外的Java錯誤,* c)*不惜一切代價避免(* Spring *框架浮現在腦海中,但它遠非唯一)。你還有一大堆在JVM之上運行的語言,它決定讓這個「特性*出語言......例如 – SyntaxT3rr0r 2011-04-14 08:46:42

+0

...... 250 000中等代碼庫,在這裏我們沒有定義一個單一的checked異常和我們沒有拋出單個檢查異常的地方。所以,你需要閱讀關於檢查異常的內容。 :) – SyntaxT3rr0r 2011-04-14 08:48:14

回答

7

確實發現了MyException,但是您重新拋出它,因此需要捕獲一個新的活動異常。

這被稱爲檢查異常。每次調用doStuff()方法時,都需要將其封裝在MyException的try/catch中,或者可以聲明您的方法也會拋出MyException。

這保證了在編碼過程中至少會考慮已知的異常。

+0

重新拋出異常並不是真正的主要問題。關鍵是doStuff()被聲明爲能夠拋出異常,並且檢查異常,因此您必須在someMethod()中處理它(或允許它傳播)。 – davmac 2011-04-14 02:47:54

+0

@davmac - 你是對的,但是如果它被聲明瞭,但是從來沒有被拋出,它就像移除throws子句一樣是一個有效的修復... – 2011-04-17 01:42:58

+0

@Joe Zitzelberger - 不一定,異常規範是方法接口。您可能希望子類可以重寫方法定義的方式導致異常被拋出。無論如何,我的觀點是提問者得到一個錯誤,並且錯誤是由於聲明該方法拋出一個異常,而不是由於它實際拋出異常。 – davmac 2011-04-18 01:26:02

2

doStuff()方法的主體中有什麼並不重要 - 因爲您已聲明它「拋出MyException」,那麼調用方法(在此例中爲someMethod())必須要麼處理異常(通過try/catch塊),要麼聲明自己拋出相同的異常。在後一種情況下,doStuff()拋出的異常會自動傳播給someMethod()的調用者。

換句話說:您在doStuff()中捕獲異常並不重要,因爲doStuff()被聲明爲拋出異常。你甚至可以刪除doStuff()的方法主體(使其不做任何事情),你仍然必須在someMethod()中處理異常。

2

由於doStuff()再次拋出異常。你將不得不再次圍繞嘗試抓住它。

void someMethod() { 

     try 
     { 
     doStuff(); 
     } 
     catch (MyException e) 
     { 
     e.printStackTrace(); 
     } 

    } 

或者另一種選擇是不要再拋出異常。每次你拋出一個異常,它都必須被捕獲。

3

你需要「重投」從的someMethod的異常,因爲MyException是「的Checked Exception」(不繼承RuntimeException - 這是一個「未經檢查的異常」)和編譯器會強迫你處理檢查異常,就像這樣:

class MyException extends Exception { 

    /** 
    * @throws MyException because it is a checked Exception (doesn't extend RuntimeException) and the compiler 
    * forces you to handle Checked Exceptions. 
    */ 
    void someMethod() throws MyException { 
     doStuff(); 

    } 

    void doStuff() throws MyException { 
     try { 
      throw new MyException(); 
     } catch (MyException me) { 
      throw me; 
     } 
    } 
} 

或者你需要處理MyException一些方法,以便編譯器是幸福的,就像這樣:

class MyException extends Exception { 


    void someMethod() { 
     try { 
      doStuff(); 
     } catch (MyException ex) { 
      //Do Something useful with the Exception... 
      Logger.getLogger(MyException.class.getName()).severe("A Severe Exception Message"); 
     } 

    } 

    void doStuff() throws MyException { 
     try { 
      throw new MyException(); 
     } catch (MyException me) { 
      throw me; 
     } 
    } 
}