2017-12-18 390 views
1

爲什麼下面的代碼編譯正常,但被調用的方法不需要拋出Exception?是不是Exception檢查異常,而不是未經檢查的異常?請澄清。異常不需要被拋出,但IOException異常

class App { 
    public static void main(String[] args) { 
     try { 
      amethod(); 
      System.out.println("try "); 
     } catch (Exception e) { 
      System.out.print("catch "); 
     } finally { 
      System.out.print("finally "); 
     } 
     System.out.print("out "); 
    } 
    public static void amethod() { } 
} 

如果我想使用一個IOexception嘗試捕捉(checked exception)時,該方法被調用需要扔IOException。我明白了。

import java.io.IOException; 

class App { 
    public static void main(String[] args) { 
     try { 
      amethod(); 
      System.out.println("try "); 
     } catch (IOException e) { 
      System.out.print("catch "); 
     } finally { 
      System.out.print("finally "); 
     } 
     System.out.print("out "); 
    } 
    public static void amethod() throws IOException { } 
} 
+2

我認爲你的理解是倒退的。 'throws'聲明的目的是列出被調用者拋出的選中的異常,而不是被調用者捕獲的異常。 –

回答

1

不是 '例外' checked異常,而不是一個未經檢查的異常?

是的。

但即使我們知道該方法本身不會丟棄Exception本身,代碼catch(Exception e){仍然可以執行。 try塊中的代碼仍然可以拋出繼承自Exception的內容。這包括RuntimeException及其子類,它們未被選中。

catch(IOException e){另一方面,只能捕獲檢查異常。 (Java不允許多繼承,所以任何屬於IOException的子類都不可能是RuntimeException的子類。)編譯器可以很容易地發現try塊中的任何代碼都不可能拋出IOException(因爲任何引發檢查異常的方法都必須明確地說明),從而允許它標記代碼。

+0

完美!容易明白 –

1

您正在觀察的行爲來自Java語言規範在這種情況下專門處理Exception的事實。據§11.2.3

這是一個編譯時錯誤,如果catch子句能趕上檢查異常E類,這是不是相當於catch子句try塊的情況下可以拋出除E 爲ExceptionException的超類之外的作爲E 的子類或超類的檢查異常類。

這是合理的,因爲Exception(和它的超類Throwable)可以被用來捕捉延伸RuntimeException也異常。由於運行時異常總是可行的,編譯器總是允許Exception出現在catch子句中,而不管是否存在已檢查的異常。