2017-05-02 45 views
0
public class s1 { 

    void m1(){ 
     m2(); 
    } 

    String m2() throws IOException{ 
     BufferedReader inputFile = new BufferedReader(new FileReader("a.txt")); 
     String line = inputFile.readLine(); 
     inputFile.close(); 
     return line; 
    } 
} 


public class Main { 
    public static void main(String[] args) { 
     s1 obj1 = new s1(); 
     try { 
      obj1.m1(); 
     } 
     catch (Exception e){ 
      System.out.println("I got it!"); 
     } 
    } 
} 

當我運行這段代碼,我從main方法的檢查異常

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
Unhandled exception type IOException 

我感到困惑的是消息,因爲我認爲我處理這個檢查IOException異常的主要方法處理。然而,編譯器希望我也將throws添加到void m1()。這樣做的主要原因是什麼?

+1

每一個方法調用平方米必須確定它是如何HANDELS是例外。那確實包括m1。 –

+0

'm1'調用'm2','m2'拋出'IOException'。但'm1'不處理異常,因此您必須選擇:make'm1'引發異常,或爲'm2'調用添加'try/catch'塊 –

+0

與'm2'完全相同捕獲或聲明拋出可能在其調用的方法中發生的'IOException'(例如'readLine()'),'m1'也必須執行相同的操作,因爲它會調用一個方法('m2()') IOException'。 – Berger

回答

0

你的方法m1調用另一個方法m2它拋出異常,所以m1必須拋出它,這就是Java的設計。

如果您在方法m2中使用try/catch來捕獲該異常,則不需要向其中添加throws。因此,如果您不想將throws IOException添加到m2以及所有調用m2的內容,請立即在此方法中抓取它。

1

由m1調用的方法m2引發異常。所以,你應該:

添加throws IOException於方法M1

呼叫try塊裏面的方法M2

因爲有些事情必須與M2拋出的異常做了,無論是被抓住再被拋出。

0

編譯器希望我將void拋出也添加到void m1()中。 這是什麼主要原因?

有異常處理的兩個主要方面,報告恢復。在Java異常處理中提供了一種靈活的機制,用於將控制從錯誤點報告傳遞到補充恢復處理程序。

throws子句向您的方法的調用者發出信號,表示它可能會遇到IOException。然後,調用者需要做出與相同的決定,處理該異常或告訴其調用者該異常可能被拋出。

簡單地說,如果一個方法是使用throws條款那麼這個隱含告訴其他方法 - 「如果你給我打電話,你必須處理這些異常,我扔」。

0

方法m2可能會拋出一個IOException
由於m1調用m2m1也可能會拋出此異常。
IOException不是從RuntimeException派生的,所以它可能被拋出的事實應該被明確地聲明。
換句話說,將throws IOException添加到m1的聲明中。

0

任何調用引發任何Checked異常的方法的方法都必須處理它們或拋出它們。如果不是通過捕獲來處理,那麼在該方法的簽名中必須聲明異常,以使得這種方法的調用者知道要處理的異常。檢查異常是針對某些特殊情況的故意,必須予以處理或拋出。在你的情況下,因爲m2()拋出一個checkedException和m1()調用m2()因此它是m1()的方法的簽名的責任,讓任何呼叫者m1()知道有必要處理的例外情況的可能性。請注意,在你的情況下,你只是從主要方法調用它,但不會阻止你或任何其他開發人員在將來中使用任何其他方法調用它。引發檢查異常的方法的責任是聲明存在異常情況並需要處理,調用者只是處理它們。

希望您現在明白您需要修改m1()的簽名併爲IOException添加缺少的聲明。

0

讓我們看看JLS: 11.3. Run-Time Handling of an Exception說什麼。

當一個異常被拋出(§14.18),控制從導致該異常到最近的代碼傳送動態包圍catch子句,如果有的話,在try語句(§14.20),其能夠處理該異常的。

...

如果無法找到能夠處理異常的catch子句,那麼當前線程(即遇到異常的線程)終止。結束之前,所有的最終條款是根據以下規則執行,未捕獲異常的處理:

和之後的例子:

方法運動員的聲明必須有一個throws子句,因爲它可以拋出TestException異常,這是一個檢查的異常類(§11.1.1)。如果throws子句被省略,則會發生編譯時錯誤。

這最後一條語句恰好就是您的情況,m1省略了throws子句,因此會發生編譯時錯誤。添加throws IOException或此異常的任何超類/接口來糾正此錯誤。

注: 有趣的是,要注意的是,如果你試圖抓住從main一個IOException與你實際的代碼,你會得到一個其他的編譯時錯誤追趕一輛unthrowned例外。但Exception不是這種情況,因爲這隻發生在檢查異常,因爲Exception可以但未經檢查的異常RuntimeException,情況並非如此。

更多信息JLS : 11.2. Compile-Time Checking of Exceptions

相關問題