在某些情況下例外的發生是可預期的,例如使用輸入輸出功能時,可能會由於硬體環境問題,而使得程式無法正常從硬體取得輸入或進行輸出,這種錯誤是可預期發生的,像這類的例外稱之為「受檢例外」(Checked Exception),對於受檢例外編譯器會要求您進行例外處理,例如在使用 java.io.BufferedReader 的 readLine() 方法取得使用者輸入時,編譯器會要求您於程式碼中明確告知如何處理 java.io.IOException,範例 10.2 是個簡單的示範。
import java.io.*;
public class CheckedExceptionDemo {
public static void main(String[] args) {
try {
BufferedReader buf = new BufferedReader(
new InputStreamReader(System.in));
System.out.print("請輸入整數: ");
int input = Integer.parseInt(buf.readLine());
System.out.println("input x 10 = " + (input*10));
}
catch(IOException e) { // checked exception
System.out.println("I/O錯誤");
}
catch(NumberFormatException e) { // runtime exception
System.out.println("輸入必須為整數");
}
}
}
IOException 是受檢例外,是可預期會發生的例外,編譯器要求您必須處理,如果您不在程式中處理的話,例如將 IOException 的 "catch" 區塊拿掉,編譯器會回報錯誤訊息:
CheckedExceptionDemo.java:9: unreported exception java.io.IOException; must be caught or declared to be thrown
範例 10.2 中試著從使用者輸入取得一個整數值,由 BufferedReader 物件所讀取到的輸入是個字串,您使用 Integer 類別的 parseInt() 方法試著剖析該字串為整數,如果無法剖析,則會發生錯誤並丟出一個 NumberFormatException 例外物件,當這個例外丟出後,程式會離開目前執行的位置,而如果設定的 "catch" 有捕捉這個例外,則會執行對應區塊中的陳述句,注意當例外一但丟出,就不會再回到例外的丟出點了。
像 NumberFortmatException 例外是「執行時期例外」(Runtime exception),也就是例外是發生在程式執行期間,並不一定可預期它的發生,編譯器不要求您一定要處理,對於執行時期例外若沒有處理,則例外會一直往外丟,最後由 JVM 來處理例外,JVM 所作的就是顯示例外堆疊訊息,之後結束程式。
如果 try...catch 後設定有 "finally" 區塊,則無論例外是否有發生,都一定會執行 "finally" 區塊。