
例外处理课件.ppt
143页著作權所有 © 旗標出版股份有限公司第第 14 章章例外處理例外處理1本章提要本章提要l14-1 甚麼是例外?l14-2 try/catch/finally 敘述l14-3 抛出例外l14-4 自訂例外類別l14-5 綜合演練2《例外处理》PPT课件前言前言 在整個程式的生命週期中, 難免會發生一些問題或錯誤, 大概可分為以下幾類:l編譯時期錯誤編譯時期錯誤:這是在程式開發過程中所發生的, 例如初學者最常遇到的語法錯誤就屬於其中一像是寫程式時忘了在敘述後面加分號、變數名稱打錯等等, 如此一來在編譯程式時就無法編譯成功, 因此稱之為編譯時期錯誤編譯時期錯誤 (compiler-time error)3《例外处理》PPT课件前言前言l邏輯錯誤邏輯錯誤:這種錯誤是指程式雖能編譯成功、也能正常執行, 但執行的結果卻不是我們所預期的l換言之是程式的邏輯有問題所產生的錯誤, 例如您要寫一個程式計算球體體積, 但將計算公式轉成程式的形式時, 不小心打錯了, 導致計算結果不正確, 這就是一種邏輯錯誤4《例外处理》PPT课件前言前言l執行時期錯誤執行時期錯誤:此錯誤也是在程式編譯成功後, 於執行階段發生的錯誤, 但執行時期錯誤 (run-time error) 是指程式本身邏輯沒有問題, 但在執行時發生當初設計程式時, 未預期的狀況, 導致程式無法正常執行的情形。
l舉例來說, 如果程式中有除法運算, 但用來當除數的整數變數其值為 0 (可能是使用者輸入錯誤), 就會使程式發生除以 0 的錯誤5《例外处理》PPT课件前言前言l本章要介紹的例外處理例外處理, 就是要處理執行時期錯誤, 讓我們的程式即使遇到突發狀況時, 也能執行完成6《例外处理》PPT课件14-1 甚麼是例外?甚麼是例外?l簡單的說, 程式執行時期, 所發生的不可預期錯誤就可稱為例外例外 (Exception)發生例外時, Java 程式將會不正常中止, 輕則讓使用者覺得程式有問題、重則導致使用者的資料毀損/ 喪失為了讓 Java 程式設計人員能設計出安全可靠 (robust) 的程式, 不會因例外發生, 程式就什麼事都不能做, 因此 Java 語言特別內建了例外處理的功能7《例外处理》PPT课件有狀況:引發例外有狀況:引發例外l在第二章曾介紹過, Java 程式是在 Java 虛擬機器 (JVM) 中執行的在預設的情況下, 當程式執行時發生例外, JVM 就會攔截此例外狀況, 並拋出 (throw) 此例外事件8《例外处理》PPT课件例外案例之一:使用者輸入錯誤例外案例之一:使用者輸入錯誤l使用者輸入非程式預期資料, 而導致例外, 是典型的例外案例。
l在前幾章我們都有使用到由鍵盤取得使用者輸入的範例程式, 而只要我們故意輸入非程式所需的資料, 就會發生例外l例如下面這個第 6 章的畫三角形範例:9《例外处理》PPT课件例外案例之一:使用者輸入錯誤例外案例之一:使用者輸入錯誤10《例外处理》PPT课件例外案例之一:使用者輸入錯誤例外案例之一:使用者輸入錯誤11《例外处理》PPT课件例外案例之一:使用者輸入錯誤例外案例之一:使用者輸入錯誤12《例外处理》PPT课件例外案例之一:使用者輸入錯誤例外案例之一:使用者輸入錯誤l由於第 13 行呼叫的 Integer.parseInt() 方法只能解讀以數字構成的字串, 而我們故意輸入文字或是有小數點的數字, 就會導致程式無法解讀, 而引發例外 (另一種說法是:拋出例外)l此時 Java 會顯示一連串例外的相關訊息, 並中止程式執行 (另一說法是執行緒被終止, 關於執行緒請見下一章), 因此第 15 行以下的程式也不會執行到13《例外处理》PPT课件例外案例之一:使用者輸入錯誤例外案例之一:使用者輸入錯誤l在例外訊息中, 可看到例外所屬的 『例外類別』:14《例外处理》PPT课件例外案例之二:程式設計不當例外案例之二:程式設計不當l另一種可能引發例外的情況是程式設計不當, 例如在第 8 章介紹陣列時提過, 當程式中使用的元素索引碼超出陣列範圍, 就會產生例外:15《例外处理》PPT课件例外案例之二:程式設計不當例外案例之二:程式設計不當16《例外处理》PPT课件例外案例之二:程式設計不當例外案例之二:程式設計不當l從執行結果我們可以看到, 當程式執行到 i 的值等於 4 的時候, 由於 4 已超出陣列元素的索引範圍, 所以執行到第 8 行程式時, 存取 a[i] (相當於 a[4]) 的動作就會引發例外。
17《例外处理》PPT课件例外案例之二:程式設計不當例外案例之二:程式設計不當l同樣的, 這個範例也是在 Java 輸出一長串的訊息後, 程式就停止執行了, 因此第 10 行的敘述也不會被執行到l這個範例所引發的例外, 所屬的類別和前一個例子也不同:18《例外处理》PPT课件Java 程式處理例外狀況的方式程式處理例外狀況的方式l例外處理流程l例外類別19《例外处理》PPT课件例外處理流程例外處理流程l當程式執行時發生了例外, Java 會拋出 (throw) 例外, 也就是將例外的相關資訊包裝在一個例外物件之中, 然後丟給目前執行的方法來處理, 此時會有兩種狀況:l如果方法中沒有沒有處理這個例外的程式碼, 則轉向呼叫者 (呼叫該方法的上一層方法) 尋找有無處理此例外的程式碼若一直找到最上層的 main() 都沒有處理這個例外的程式碼發生時, 該程式將會停止執行20《例外处理》PPT课件例外處理流程例外處理流程l若程式中有處理這個例外的程式碼, 則程式流程會跳到該處繼續執行 (詳細流程請參見下一節說明)l以前面陣列索引碼超出範圍的例子而言, 該例外是在 main() 方法中拋出的, 所以 Java 會看 main() 中是否有處理該例外的處理程式, 以便將例外物件拋給它處理。
21《例外处理》PPT课件例外處理流程例外處理流程l不過在我們的範例程式中當然是沒有任何例外處理程式, 而 main() 又是最上層的方法 (畢竟程式是由它開始執行的), 所以這個例外只好由 Java 自己來處理, 而它的處理方式很簡單, 就是印出一段有關該例外的訊息, 並終止程式的執行, 由前面的執行結果即可印證22《例外处理》PPT课件例外處理流程例外處理流程l如果希望例外發生時, 程式不會莫名其妙的停止執行, 就必須加入適當的例外處理程式以陣列索引碼超出範圍為例, 我們必需在 main() 方法中撰寫處理相關的例外物件, 此物件所屬的類別就是出現在錯誤訊息中的 ArrayIndex OutOfBoundsException23《例外处理》PPT课件例外處理流程例外處理流程l而處理這類例外的相關程式碼, 在 Java 中通常稱之為 『捕捉』 (catch) ArrayIndexOutOfBoundsException 例外的程式24《例外处理》PPT课件例外類別例外類別l在 Java 中, 所有拋出的例外都是以 Throwable 類別及其衍生類別所建立的物件來表示, 像 NumberFormatException、ArrayIndexOutOfBoundsException 都是其衍生類別。
lThrowable 類別有兩個子類別:Error 和Exception 分別代表兩大類的 Java 例外, 而這兩個類別之下又各有許多子類別和衍生類別, 分別代表不同類型的例外25《例外处理》PPT课件例外類別例外類別lError 類別類別:此類別及其衍生類別代表的是嚴重的錯誤, 例如系統資源不足, 導致程式無法執行、或是 JVM 本身發生錯誤l由於此類錯誤通常也是我們無法處理的, 所以一般我們不會在程式中捕捉此類的例外物件26《例外处理》PPT课件例外類別例外類別lException 類別類別:此類別及其衍生類別就是代表一般的例外, 也是一般撰寫錯誤處理程式所會捕捉的類別lException 類別之下則有多個子類別, 但在本章中我們將重點放在 RuntimeException 這個子類別27《例外处理》PPT课件例外類別例外類別28《例外处理》PPT课件例外類別例外類別l顧名思義, RuntimeException 類別代表的就是『執行時的例外』l此類別下有多個子類別和衍生類別分別代表不同類型的執行時期例外l例如前面提過的, 在程式中指定超過範圍的索引碼時, 就會引發 ArrayIndexOut OfBoundsException 類別的例外。
l此類別是 RuntimeException的孫類別, 其父類別是 IndexOutOfBoundsException29《例外处理》PPT课件例外類別例外類別l另一種我們有時會遇到的例外, 則是RuntimeException 的另一個子類別 ArithmeticException 的例外物件, 當程式中做數學運算時發生錯誤情況 (例如前面提過的除以 0), 就會引發這個例外l接下來我們就來看要如何用 Java 程式捕捉這類例外30《例外处理》PPT课件14-2 try/catch/finally 敘述敘述l在 Java 程式中撰寫例外處理程式, 可使用 try、catch、finally 三個敘述l但以最簡單的捕捉例外程式, 只需用到 try 和 catch 敘述即可31《例外处理》PPT课件捕捉例外狀況捕捉例外狀況ltry 和 catch 敘述的意思很簡單, 當我們要執行一段有可能引發例外的程式, 我們就將它放在 try 區塊中, 同時用 catch 敘述來捕捉可能被拋出的例外物件, 並撰寫相關的處理程式l其結構如下:32《例外处理》PPT课件捕捉例外狀況捕捉例外狀況33《例外处理》PPT课件捕捉例外狀況捕捉例外狀況ltry 是嘗試的意思, 所以上列的結構就像是『嘗試執行一段可能引發例外的敘述』, 如果的則發生例外時, 就由捕捉 (catch) 該例外的區塊來處理。
34《例外处理》PPT课件捕捉例外狀況捕捉例外狀況35《例外处理》PPT课件捕捉例外狀況捕捉例外狀況l舉個最簡單的例子, 若要捕捉之前所提的 ArrayIndexOutOfBoundsException 例外, 可用如下範例的 try/catch 段落來處理:36《例外处理》PPT课件捕捉例外狀況捕捉例外狀況37《例外处理》PPT课件捕捉例外狀況捕捉例外狀況38《例外处理》PPT课件捕捉例外狀況捕捉例外狀況1.第 7〜17 行就是整個 try/catch 區塊第 7〜11 行的 try 區塊, 就是單純用迴圈輸出所有的陣列元素當迴圈變數 i 的值為 4 時, 執行第 10 行程式就會引發例外2.第 11〜17 行就是捕捉超出陣列範圍例外的 catch 區塊第 15 行程式直接輸出例外物件 e 的內容39《例外处理》PPT课件捕捉例外狀況捕捉例外狀況3.不管有沒有發生 ArrayIndexOutOfBoundsException 例外, 都會執行到第 19 行的程式l如果是在撰寫商用程式, 隨便顯示一行例外訊息, 對使用者來說並不友善, 因為使用者可能根本不懂 Java 程式語言, 根本不瞭解什麼是『例外』;或是不能完全明白為什麼發生錯誤。
40《例外处理》PPT课件捕捉例外狀況捕捉例外狀況l此時若能讓程式顯示更多的相關資訊, 可幫助使用者瞭解問題所在, 例如需要使用者輸入資料的應用程式, 能回應使用者可能因為輸入什麼樣的錯誤資料, 導致程式發生問題更好l以下就是在 catch 區塊中顯示與例外相關訊息的範例41《例外处理》PPT课件捕捉例外狀況捕捉例外狀況42《例外处理》PPT课件捕捉例外狀況捕捉例外狀況43《例外处理》PPT课件捕捉例外狀況捕捉例外狀況44《例外处理》PPT课件捕捉例外狀況捕捉例外狀況l這個範例程式內建一個整數陣列, 並請使用者自行選擇要看陣列中的哪一個數字l如果使用者指定的數字超出範圍, 就會引發 ArrayIndexOutOf BoundsException 的例外, 在 catch 區塊中, 會顯示這個程式只有 5 個數字, 並告知使用者指定的數字超出範圍45《例外处理》PPT课件捕捉多個例外捕捉多個例外l如果程式中雖有 try/catch 敘述捕捉特定的例外, 但在執行時發生了我們未捕捉的例外, 會發生什麼樣的狀況呢?很簡單, 就和我們沒寫任何 try/catch 敘述一樣, Java 會找不到處理這個例外的程式, 因此程式會直接結束執行。
l我們直接用剛剛的 CatchAndShowInfo.java 來示範:46《例外处理》PPT课件捕捉多個例外捕捉多個例外47《例外处理》PPT课件捕捉多個例外捕捉多個例外l如以上執行結果所示, 雖然程式中有捕捉 ArrayIndexOutOfBoundsException, 但只要使用者輸入整數以外的內容, 就會使 Integer.parseInt() 方法因無法解譯而拋出 NumberFormatException 例外, 由於程式未捕捉此例外, 因而導致程式意外結束48《例外处理》PPT课件捕捉多個例外捕捉多個例外l要用 try/catch 敘述來解決這個問題, 我們可讓程式再多捕捉一個 ArithmeticException 例外, 也就是讓程式有兩個 catch 段落l寫法很簡單, 只要讓 2 個 catch 段落接連列在 try 區塊之後即可例如:49《例外处理》PPT课件捕捉多個例外捕捉多個例外50《例外处理》PPT课件捕捉多個例外捕捉多個例外l請參考以下的範例程式:51《例外处理》PPT课件捕捉多個例外捕捉多個例外52《例外处理》PPT课件捕捉多個例外捕捉多個例外53《例外处理》PPT课件捕捉多個例外捕捉多個例外1.第 18 行將呼叫 Integer.parseInt() 方法的敘述移到 try 區塊中, 以便程式能捕捉此方法可能拋出的例外。
2.第 26 捕捉 NumberFormatException 例外, 並在第 27 行顯示錯誤訊息54《例外处理》PPT课件捕捉多個例外捕捉多個例外l雖然我們可以用多個 catch 敘述來捕捉不同類型的例外, 但若可能發生的例外種類較多, 那要加好幾個 catch 敘述也有些麻煩, 而且也難保不會有所遺漏在此情況下, 可考慮捕捉『上層』的例外類別l在介紹此方法前, 我們再來對 Java 的例外處理機制做更進一步的認識55《例外处理》PPT课件自成體系的例外類別自成體系的例外類別lThrowable 類別lException 類別l捕捉上層的例外56《例外处理》PPT课件Throwable 類別類別l如前所述, Java 所有的例外都是以 Throwable 類別及其衍生類別所建立的物件 lThrowable 類別本身已定義了數個方法, 這些方法也自然由其衍生類別所繼承, 所以我們在處理所有例外時, 也可叫用這些方法l不過這些方法中, 有些是用於自訂例外類別、部份則是進階的程式除錯才會用到, 我們就不深入探討l另外 Throwable 類別也定義了兩個可傳回例外相關資訊的方法:57《例外处理》PPT课件Throwable 類別類別l上述 2 個方法的用法, 可參考以下的範例程式:58《例外处理》PPT课件Throwable 類別類別59《例外处理》PPT课件Throwable 類別類別60《例外处理》PPT课件Throwable 類別類別61《例外处理》PPT课件Throwable 類別類別lThrowable 只有 Error 和 Exception 兩個子類別, 其中 Error 類別代表系統的嚴重錯誤, 通常不需由程式處理, 也就是說我們不需撰寫捕捉此類敘述的 catch 敘述。
l而 Exception 類別下則有許多衍生類別分別代表一般寫程式時可能遇到的例外, 因此以下我們進一步介紹 Exception 類別及其衍生類別62《例外处理》PPT课件Exception 類別類別lException 類別之下的子類別種類相當多, 而各子類別下又有或多或少的不同子類別l除了 RuntimeException 外, Exception 的子類別都是呼叫 Java 標準類別庫中特定的方法, 或是在我們程式要自己拋出類別時才會用到, 初學者大都只會用到 RuntimeException 這個子類別下的某幾個類別63《例外处理》PPT课件Exception 類別類別l除了我們已用過的 ArrayIndexOutOfBoundsException 和 ArithmeticException 外, 我們再介紹幾個 RuntimeException 下的子類別和孫類別64《例外处理》PPT课件Exception 類別類別lNullPointerException:當程式需使用一個指向物件的參照, 但該參照卻是 null 時就會引發此例外l例如程式需要參考一個物件, 但我們提供的物件參照卻是 null, Java 就會拋出 NullPointerException 例外的物件。
lNegativeArraySizeException:陣列大小為負數時, 就會引發此例外65《例外处理》PPT课件Exception 類別類別lNumberFormatException:當程式要將某個字串轉換成數值格式, 但該字串的內容並不符該數值格式的要求, 就會引發此例外l在前面的範例已看過, 呼叫 Integer.parseInt() 方法要將字串轉成整數時, 若參數字串並非整數的形式, 就會引發格式不合的例外66《例外处理》PPT课件Exception 類別類別lStringIndexOutOfBoundsException:和 ArrayIndexOutOfBoundsException 一樣同屬 IndexOutOfBoundsException 的子類別, 當程式中存取字串中字元, 但指定的索引超出字串範圍時, 就會引發此例外67《例外处理》PPT课件Exception 類別類別68《例外处理》PPT课件捕捉上層的例外捕捉上層的例外l大致瞭解主要的例外類別繼承關係後, 我們就來看如何捕捉上層的例外類別物件l其實方法也很簡單, 只要寫一個 catch 敘述, 並捕捉 Exception 或 RuntimeException 類別的物件即可, 例如下面這個簡單的程式:69《例外处理》PPT课件捕捉上層的例外捕捉上層的例外70《例外处理》PPT课件捕捉上層的例外捕捉上層的例外71《例外处理》PPT课件捕捉上層的例外捕捉上層的例外72《例外处理》PPT课件捕捉上層的例外捕捉上層的例外73《例外处理》PPT课件捕捉上層的例外捕捉上層的例外l第 28 行的 catch 敘述捕捉的是 IndexOutOfBoundsException 例外物件, 所以不管發生 ArrayIndexOutOfBoundsException 或是 StringIndexOutOfBoundsException 例外, 都會被捕捉, 並執行 29、30 行敘述輸出相關訊息。
l如果把 28 行的程式改成捕捉更上層的 RuntimeException 例外物件, 或是 Exception 例外物件, 也具有相同的效果74《例外处理》PPT课件針對衍生例外類別做特別處理的寫法針對衍生例外類別做特別處理的寫法l在捕捉上層例外時, 如果您想針對某個子類別的例外進行處理, 可利用前面介紹過的捕捉多個例外類別的技巧:先捕捉該子類別;再捕捉上層類別l例如假設有一段程式碼可能產生多種 Runtime Exception 衍生類別的例外, 但我們想特別對ArrayIndexOutOfBoundsException 的例外做額外處理, 可將程式寫成:75《例外处理》PPT课件針對衍生例外類別做特別處理的寫法針對衍生例外類別做特別處理的寫法76《例外处理》PPT课件針對衍生例外類別做特別處理的寫法針對衍生例外類別做特別處理的寫法l請注意, 上列 2 段 catch() 敘述的順序不可倒過來, 因為若寫成:77《例外处理》PPT课件針對衍生例外類別做特別處理的寫法針對衍生例外類別做特別處理的寫法l則發生 ArrayIndexOutOfBoundsException 例外時, 由於 Java 找到第 1 個 catch 段落時, 因為 ArrayIndexOutOfBoundsException 為 RuntimeExceptione 的衍生類別, Java 就會將例外丟給它處理, 使得第 2 個 catch 段落永遠都不會被執行。
78《例外处理》PPT课件善後處理機制善後處理機制l回顧一下 Java 中發生例外時的流程, 當 try 區塊中的程式發生例外時, 會先看程式中有無對應的 catch 敘述, 有則執行該 catch 區塊的程式, 沒有就結束程式的執行l因此若您沒有捕捉到程式可能發生的例外, 導致程式突然結束執行, 有時會有些不良的影響, 例如程式可能還沒將重要資料存檔, 導致使用者的重要資料喪失79《例外处理》PPT课件善後處理機制善後處理機制l為了讓程式能在發生例外後, 做一些善後處理工作, Java 提供了一個 finally 敘述l此敘述的用法和 try/catch 類似, 我們只需將善後程式碼放在 finally 區塊, 並將此區塊放在 try/catch 之後即可形成一完整的 try/catch/finally 例外處理段落80《例外处理》PPT课件善後處理機制善後處理機制81《例外处理》PPT课件善後處理機制善後處理機制82《例外处理》PPT课件善後處理機制善後處理機制l此時程式執行的流程如右圖:83《例外处理》PPT课件善後處理機制善後處理機制l由於不管何種情況都會執行到 finally 區塊, 所以很適合用 finally 來做必要的善後處理, 例如嘗試儲存使用者尚未存檔的資料等。
l若先前未發生例外或是發生程式有捕捉的例外, 則在執行完 finally 區塊後, 程式仍會依正常流程繼續執行;但若之前發生的是程式未捕捉的例外, 在執行完 finally 區塊後, Java 仍會顯示例外訊息並停止執行程式84《例外处理》PPT课件善後處理機制善後處理機制l讓我們來看以下這個例子:85《例外处理》PPT课件善後處理機制善後處理機制86《例外处理》PPT课件善後處理機制善後處理機制87《例外处理》PPT课件善後處理機制善後處理機制l在第 09、10 行故意加了兩行除以零的運算, 以引發 ArithmeticException 例外, 而程式中並未捕捉此例外物件l但當 Java 拋出此例外時, 程式仍會執行到 21 行 finally 區塊中的敘述後, 才停止執行l也因為例外的發生, 所以第23 行的程式不會被執行88《例外处理》PPT课件善後處理機制善後處理機制l讀者可試一下在第 10 行程式前面加上 "//" 使其變成註解, 重新編譯、執行程式, 此時您就會發現程式引發 IndexOutOfBoundsException 例外後, 第 21、23 行的敘述都會被執行。
89《例外处理》PPT课件14-3 拋出例外拋出例外l將例外傳遞給呼叫者l自行抛出例外90《例外处理》PPT课件將例外傳遞給呼叫者將例外傳遞給呼叫者l在開發 Java 程式時, 若預期程式可能會遇到自己無法處理的例外時, 我們可以選擇拋出例外, 讓上層的程式 (例如呼叫程式的程式) 去處理l要拋出例外需使用 throw 以及 throws 敘述, throws 敘述我們也已用過很多次, 每當要從鍵盤讀入使用者輸入時, main() 方法後面就會加上 "throws IOException" 的註記, 以下說明為何 main() 方法要加上此段敘述91《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外l除了根據例外類別的繼承關係將例外類別分為 Error 和 Exception 兩大類外, 還有一種分類方式, 是根據編譯器在編譯程式時, 是否會檢查程式中有沒有妥善處理該種例外:此時可將例外分成 Unchecked (不檢查) 和 Checked (會檢查) 兩種92《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外lUnchecked 例外例外:所有屬於 Errors 或 RuntimeException 的衍生類別的例外都歸於此類, 前者是我們無法處理的例外。
l而後者則是可利用適當的程式邏輯避免的例外 (例如做除法運算前先檢查除數是否為 0、存取陣列前檢查索引碼是否超出範圍)l所以 Java 並不要求我們在程式處理此類例外, 因此稱之為編譯器『不檢查的』 (Unchecked) 例外93《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外lChecked 例外例外:除了 RuntimeException 以外, 所有 Exception 的衍生類別都屬於此類lJava 語言規定, 所有的方法都必須處理這類例外, 因此稱之為編譯器『會檢查的』 (Checked) 例外, 如果我們不處理的話, 在編譯程式時就會出現錯誤, 無法編譯成功94《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外l以前幾章我們在 main() 方法中取得鍵盤輸入的程式為例, 由 BufferedReader 類別的 readLine() 方法的原型宣告可發現它可能會拋出 IOException 例外l而 IOException 正屬於 Checked 例外之一, 因此使用到這個方法時, 我們就必須在程式中『處理』這個例外, 處理方式有二:95《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外l自行用自行用 try/catch 敘述來處理敘述來處理:以使用 readLine() 方法為例, 我們必須用 try 段落包住執行 readLine() 方法的敘述, 然後用 catch 敘述來處理 IOException 例外。
l但初學 Java 時, 暫時不必做此種複雜的處理, 因此可採第 2 種方式96《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外l將將 Checked 例外拋給上層的呼叫者處理例外拋給上層的呼叫者處理:當我們在 main() 方法後面加上 "throws IOException" 的宣告, 就表示 main() 方法可能會引發 IOException 例外, 而且它會將此例外拋給上層的呼叫者 (在此為 JVM) 來處理這也是一般程式會採用的方式l另一方面, 在撰寫自訂的方法時, 若此方法會拋出例外, 必須在方法宣告中用 "throws" 敘述, 註明所有可能拋出的例外類別種類97《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外l如果我們不將 main() 方法宣告為 "throws IOException" 的話, 就必須用 try/catch 的方式來處理 BufferedReader 類別的 readLine() 方法, 或其它會拋出 Checked 例外的方法l例如我們可將先前的範例改寫如下:98《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外99《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外100《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外101《例外处理》PPT课件認識認識 Checked/Unchecked 例外例外l原本使用 readLine() 這類方法時, 不在 main() 方法宣告 "throws IOException", 編譯程式時就會出現錯誤。
l但我們現在改用 try 來執行 readLine(), 並自行捕捉 IOException 類別的例外, 因此不宣告 "throws IOException" 也能正常編譯成功102《例外处理》PPT课件自行拋出例外自行拋出例外l當我們遇到無法自己處理的例外, 或是想以例外的方式來通知不正常的狀況時, 就可以用 throw 敘述主動拋出例外l舉例來說, 在 Java 中, 整數運算的除以 0 會引發 ArithmeticException 例外, 但除以浮點數 0.0 時卻不會引發例外, 只會使執行結果變成 NaN (參見第 17 章)103《例外处理》PPT课件自行拋出例外自行拋出例外l如果您希望這個計算也會產生 ArithmeticException 例外, 則可自行將程式設計成發現除數為 0.0 時, 即拋出 ArithmeticException 例外物件104《例外处理》PPT课件自行拋出例外自行拋出例外105《例外处理》PPT课件自行拋出例外自行拋出例外106《例外处理》PPT课件自行拋出例外自行拋出例外107《例外处理》PPT课件自行抛出例外自行抛出例外l在第 18 行我們用 if 敘述判斷使用者輸入的值是否為 0, 因為 0 將使 26 行的運算式無法算出正常結果, 所以我們在 19 行拋出 ArithmeticException 物件, 並自訂該例外物件的訊息。
108《例外处理》PPT课件14-4 自訂例外類別自訂例外類別l除了自行用 throw 敘述拋出例外物件, 我們也能自訂新的例外類別, 然後在程式中拋出此類自訂類別的例外物件l但要特別注意, 自訂的例外類別一定要是 Throwable 的衍生類別 (您可用其下的任一個子類別或孫類別來建立自訂的例外類別), 否則無法用 throw 敘述拋出該類別的物件109《例外处理》PPT课件自訂例外類別自訂例外類別l以下的範例程式是個解決雞兔同籠問題的程式, 使用者只需輸入頭的總數和腳的總數, 程式就會算出雞兔各有幾隻l程式中自訂了一個例外類別 ValueException, 當使用者輸入的數值不能在『雞有兩腳、兔有四腳』的前題下計算出雞免的數量, 程式就會拋出此自訂例外類別的物件110《例外处理》PPT课件自訂例外類別自訂例外類別111《例外处理》PPT课件自訂例外類別自訂例外類別112《例外处理》PPT课件自訂例外類別自訂例外類別113《例外处理》PPT课件自訂例外類別自訂例外類別114《例外处理》PPT课件自訂例外類別自訂例外類別115《例外处理》PPT课件自訂例外類別自訂例外類別1.第 4〜9 行是用 RuntimeException 衍生出我們自訂的 ValueException 例外類別。
其中定義了一個建構方法, 但也只是直接呼叫父類別的建構方法2.第 19〜30 行用 do/while 迴圈請使用者輸入頭數和腳數, 若輸入負值則會重新請使用者輸入116《例外处理》PPT课件自訂例外類別自訂例外類別3.第 34〜47 行的 try 區塊是在計算雞兔同籠二元聯立方程式, 用『(腳數 - 頭數*2)/2』的運算式即可算出兔子的數量, 但若計算結果不能整除, 表示使用者輸入的數值有問題, 便於 37 行拋出自訂例外類別物件;若能整除, 但商為負值, 也表示有問題, 便在第 42 行拋出例外4.第 48〜51 行 catch 自訂例外類別物件, 第 50 行顯示例外物件的訊息117《例外处理》PPT课件14-5 綜合演練綜合演練l會抛出例外的計算階乘程式l字串大小寫轉換應用l模擬汽車耗油及行駛狀況118《例外处理》PPT课件會抛出例外的計算階乘程式會抛出例外的計算階乘程式l在 6-6-3 節曾介紹一個計算階乘的範例, 我們這次做個小小的修改, 讓它改用拋出例外的方式, 來處理數值超出範圍、以及使用者不想再計算這兩種狀況119《例外处理》PPT课件會抛出例外的計算階乘程式會抛出例外的計算階乘程式120《例外处理》PPT课件會抛出例外的計算階乘程式會抛出例外的計算階乘程式121《例外处理》PPT课件會抛出例外的計算階乘程式會抛出例外的計算階乘程式122《例外处理》PPT课件會抛出例外的計算階乘程式會抛出例外的計算階乘程式1.第 12〜33 行為計算階乘的 try/catch 區塊, 計算階乘的迴圈在 26、27 行。
123《例外处理》PPT课件會抛出例外的計算階乘程式會抛出例外的計算階乘程式2.第 19 行用 if 敘述判斷使用者輸入的值是否大於 20, 若是則拋出 ArithmeticException 例外物件3.第 21 行則判斷使用者輸入的值是否為 0, 若是則拋出 RuntimeException 例外物件124《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用lJava 的 String 類別雖有 toUpperCase( )、toLowerCase( ) 可將字串中的字母全部轉成大寫或全轉成小寫, 但如果我們想做的是將字串中小寫的字轉大寫、大寫的字轉小寫, 就要自行設計相關的程式125《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用l以下就是一個將字串大小寫互換的範例程式, 這個程式只能轉換純英文字串, 換言之字串中只要含英文字母及空白以外的字元, 程式就不會進行轉換l範例程式的作法是在此情況下拋出 RuntimeException 例外物件, 並用 catch 區塊捕捉該例外、顯示相關訊息126《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用127《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用128《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用129《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用130《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用1.第 14〜39 行的 do/while 迴圈會重複請使用者輸入新字串並進行字串中大小寫變換的動作。
2.第 18〜37 用 try/catch/finally 敘述進行字串轉換的動作3.第 19〜26 行的 for 迴圈逐一進行字串中每個字元的轉換工作131《例外处理》PPT课件字串大小寫轉換應用字串大小寫轉換應用4.第 20、21 行先檢查字元是否為英文字母或空白, 是才進行轉換, 不是就在第 27 行拋出 RuntimeException 例外物件5.第 33〜37 行的 finally 區塊會在不論是否發生例外的情況下, 請使用者輸入另一個新字串6.第 38 行檢查使用者輸入的字串是否為 "bye" (不論大小寫), 若是就停止迴圈132《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況l此範例是用自訂類別來模擬汽車行駛時, 消耗油量的情況l此自訂類別會記錄汽車油箱的油量及耗油效率 (每公升可行駛的里程數)並有一個行駛指定里程數的方法, 此方法會在油料不足以行駛完指定的里程時, 拋出自訂的 NoGasException 例外物件l至於自訂的 NoGasException 例外類別, 則只單純繼承 Exception 類別, 並未改寫或新增任何成員133《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況134《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況135《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況136《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況137《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況138《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況139《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況1.第 4、5 行用 Exception 衍生出自訂的 NoGasException 例外類別。
2.第 8〜28 行定義一個 MyCar 類別以模擬汽車行走時的耗油情況此類別有兩個資料成員 GasTank 和 Efficient, 分別記錄目前油量及行走時的耗油效率140《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況3.第 18〜23 行的 go( ) 方法模擬汽車行走的情況, 程式先計算出行走指定距離時所需的油量, 再用 GasTank 減去此次的耗油量, 若剩餘油量小於零, 表示油量不足以走完指定的距離, 便在第 22 行拋出自訂的 NoGasException 例外141《例外处理》PPT课件模擬汽車耗油及行駛狀況模擬汽車耗油及行駛狀況4.第 50〜63 行使用 do/while 迴圈請使用者持續輸入要行走的距離, 直到油量用完為止5.第 56〜63 行為呼叫 go( ) 方法時的 try/catch 區塊, 若引發油料不足的例外, 就會由 61 行的 catch 敘述捕捉並輸出油料不足的訊息142《例外处理》PPT课件著作權所有 © 旗標出版股份有限公司1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0C3F6IaLdOgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5G8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjUmYp!t&w)z1C4F7JaMePhSkWnZq$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfQiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t*w-z1D4G7JbMeQhTkWoZr$u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B2E6H9LSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#s%v(y0B3E6I9LdOgRjVmYp!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1D4G7JbMePhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5G8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0C3F6IaLdOgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C4F7IaMhTkWoZr$u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!t&w)z1C4F7JaMePhSkWnZq$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYp!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t*w-z1D4G7JbMeQhTkWoZr$u(x+B2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVn%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#s%v(y0B3E6I9LdOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1D4G7JbMePhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s%v)y0C3F6IaLdOgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5G8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0C3aMePhSkWnZq$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t*w-z1D4G7JbMeQhTkWoZr$u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7IaMdPhSkVnZq$t*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!t&w)z1C4F7JaMePhSkWnZq$u*x+A2D5H8KbNfQiTlXo#s%v(y0B3E6I9LdOgRjVmYp!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t&w-D5H8KbNfQiTlXo#s%v(y0B3E6I9LdOgRjVmYp!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXp#s%v)y0B3F6I9LdOgSjVmYq!t&w-z1D4G7JbMePhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTkWoZr%u(x+B2E5H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8JbNeQhTlWo#r%u(y+B2E6H9LcOfRjUmXp!s&w)z0C4F7IaMdPgSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5H8KbNfQiTlXo#r%v(y0B3E6I9LSkVnZq$t*x-A1D5G8KbNeQiTlWo#r%v(y+B3E6H9LcOgRjUmYp!s&w)z1C4F7JaMdPhSkWnZq$u*x-A2D5G8KbNfQiTlXo#r%v(y0B3E6I9LcOgRjVmYp!t&w)z1C4G7JaMePhSkWnZr$u*x+A2D5H8KcNfQiUlXo#s%v)y0B3F6I9LdOgRjVmYq!t&w-z1C4G7JbMePhTkWnZr$u(x+A2E5H8KcNfRiUlXp#s%v)y0C3F6IaLdOgSjVnYq!t*w-z1D4G8JbMeQhTkWoZr$u(x+B2E5H9KcNfRiUmXp#s&v)y0C3F7IaLdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRjUmXp!s&v)z0C4F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6HdPgSjVnYq$t*w-A1D4G8JbNeQhTlWoZr%u(y+B2E6H9KcOfRiUmXp!s&v)z0C3F7IaMdPgSkVnYq$t*x-A1D5G8JbNeQiTlWo#r%u(y+B3E6H9LcOfRjUmYp!s&w)z0C4F7JaMdPhSkVnZq$u*x-A2D5G8KbNeQiTlXo#r%v(y+B3E6I9LcOgRjUmYp!t&w)z1C4F7JaMePhSkWnZq$u*x+A2D5H8KbNfQiUlXo#s%v(y0B3F6I9LdOgRjVmYp!t&w-z1C4G7JaMePhTkWnZr$u*x+A2E5H8KcNfQiUlXp#s%v)y0B3F6IaLdOgSjVmYq!t*w-z1D4G7JbMeQhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcjVmYq!t*w-z1D4G7JbMePhTkWoZr$u(x+A2E5H9KcNfRiUlXp#s&v)y0C3F6IaLdPgSjVnYq!t*w-A1D4G8JbMeQhTlWoZr%u(x+B2E6H9KcOfRiUmXp#s&v)z0C3F7IaLdPgSkVnYq$t*w-A1D5G8Jb143。












