2015年1月10日 星期六

Java中的Checked Exception與Unchecked Exception

2015/1/10 13:31-15:19

在這個星期,終於完完整整地將Teddy的<例外處理設計的逆襲>讀完一遍,在最後面有一個附錄叫做視力測驗,這個章節是測試自己對於書中介紹的還記得多少,全部共20題,答對其中14題以上才算及格,如果低於14題,Teddy建議讀者要再閱讀幾遍,作答過程中自己都很有把握,最後竟然才剛好對14題,差一點點就要不及格,突然回想到自己國中國小考選擇題的時候,常常把題目『下列何者錯誤』的題型看成『下列何整正確』,不是不會只是題目不小心看錯啦XD(給自己的小小藉口)。

這次稍微介紹一下Unchecked Exception和Checked Exception

在Java程式語言的例外處理中,依編譯器檢查程式碼的的觀點,分為兩類
1. 受檢例外 (Checked Exception)
2. 非受檢例外 (Unchecked Exception)


Checked Exception代表在程式編譯的期間,編譯器如果發現開發者沒有處理Checked Exception的話,它會把這個情況視為錯誤,強制開發者修正後,才能成功編譯程式。

相反地,如果例外是屬於Unchecked Excpetion,使用者不須多加處理,程式就可以通過編譯器的檢查。

在Java程式語言中,所有的例外都繼承自Throwable類別,繼承關係如下圖:




在上圖中,Throwable、Exception、IOException和SQLException屬於Checked Exception;
Error、RuntimeException、IndexOutOfException和NullPointerException屬於Unchecked Exception。



現在舉例讓各位體驗一下在撰寫Java時,遇到Unchecked Exception和Checked Exception的情況,我使用的IDE為Eclipse。

圖1 編譯器提示錯誤

圖1中,我在主程式main中呼叫了testCheckedException,它會丟出IOException,IOException屬於Checked Exception,編譯器在第11行出現一個錯誤,提示我必須在main的介面上宣告捕捉IOException,才能通過編譯器的檢查。

圖2 將例外宣告至函數介面上

圖2將IOException宣告在介面上的程式碼,此程式通過編譯器的檢查,這個例外最後會由捕捉它的人處理,也就是呼叫main的函數處理,或者呼叫main的函數可以繼續往外丟。在這個例子裡,誰會呼叫main呢?答案就是處理Java Process的Java Virtual Machine(JVM),JVM捕捉到例外之後,會將例外印在Console視窗接著把程式中止。

執行程式的結果如圖3


圖3 JVM收到例外


現在將圖1的程式,改為捕捉IOException,使用Eclipse自動修正後程式碼如圖4。


圖4 捕捉IOException且印出該例外的詳細資訊


圖4中的第14行程式碼會印出例外的詳細訊息,結果如圖5。


圖5 執行e.printStackTrace()在Console會印出例外的詳細訊息



以前剛寫Java的時候,以為程式只要發生例外,就算有捕捉(catch),程式跑完catch區塊的程式碼還是會中止,但事實不是這樣的,執行完catch區塊的程式碼後,程式還是會繼續執行下去,看以下的例子。

把圖4中的程式碼稍作修改,執行並觀察其輸出狀況如圖7。

圖6

圖7


由圖7的輸出結果可以觀察出程式執行的狀況,當程式執行到第13行時,發生IOException,程式碼直接跳到第16行執行catch區塊的程式碼,接著繼續往下執行到程式碼第20行。



接著我們繼續測試Unchecked Excpetion。


圖8

在圖8中,main呼叫了testUncheckedException(),此函數會丟出RuntimeException,它屬於Unchecked Exception,此程式直接通過編譯器的檢查。

當程式執行到第9行,main丟出例外給JVM,JVM會將例外資訊印出且中止程式。執行結果如下圖9。



圖9



以上就是今天的介紹,下回見。


我的例外處理層次好像多了一層


沒有留言:

張貼留言