《第10章例外处理.ppt》由会员分享,可在线阅读,更多相关《第10章例外处理.ppt(77页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。
1、第10章例外處理Java 2 程式設計入門與應用目錄n10-1認識例外處理機制n10-2拋出例外n10-3自訂例外類別n溫故知新n自我突破習題210-1認識例外處理機制n10-1.1檢查錯誤的第二道防線n10-1.2例外處理類別n10-1.3建立例外處理n10-1.4同時處理多個例外狀況3前言:n例外處理(Exception handling)機制是物件導向程式設計的一環,在程式語言中,所有的例外都是以類別(Class)型別存在,因此學習物件導向程式設計時,當然不能忽略例外處理類別的應用技巧。410-1.1檢查錯誤的第二道防線n程式開發過程中難免會發生程式碼錯誤的情況,而經由不斷的修正使錯誤降
2、至最低的程度。5程式語言的錯誤可分為下面三種-1:1.語法錯誤:在執行程式時,會隨時檢查程式碼中的語法是否發生錯誤,這是檢查程式碼錯誤的第一道防線,例如下面的程式碼:n上述程式碼必須先宣告變數x,否則會出現下面的錯誤訊息。6程式語言的錯誤可分為下面三種-2:2.執行時期(Run-Time)錯誤:程式語法沒有出現錯誤,且編譯期間無錯誤產生,但是在程式執行時卻無法正常執行,例如下面的程式碼:7程式語言的錯誤可分為下面三種-3:n上述程式碼必須將for迴圈的條件式修改為(int i=0;i10;i+),否則執行時會出現下面的錯誤訊息(因為i值超過陣列宣告的範圍),此訊息是例外處理機制拋出來的錯誤訊息
3、,提示程式碼執行時期發生錯誤。n因此,可以說例外處理機制是檢查程式錯誤的第二道防線。8程式語言的錯誤可分為下面三種-4:n在撰寫程式時,常見的執行時期例外錯誤有下面幾種:9程式語言的錯誤可分為下面三種-5:3.邏輯錯誤:由於程式設計師的疏忽與認知不同,在設計程式時邏輯思考的錯誤,這類的錯誤編譯器無法自動偵測出來!n例如下面的程式碼:10程式語言的錯誤可分為下面三種-6:n上述程式碼執行過程無誤,結果是“256與80的最大公因數:80”,但仔細計算,就會發現256與80的最大公因數是16,並非80。n原來是gcd函式的邏輯設計錯誤,應該將“gcd(y,y%x)”修改為“gcd(y,x%y)”,原
4、本的程式雖然照樣會顯示執行結果,但答案並非設計者想要的,這是很嚴重的錯誤!設計程式時應該特別注意,以免日後亡羊補牢。1110-1.2例外處理類別n在介紹如何建立例外處理之前,必須先了解Java有哪些例外處理類別。nJava的標準例外處理類別都定義在java.lang函式庫的Error與Exception類別中,其架構圖如下所示:12關於上述架構圖的說明如下:n圖中所有例外處理類別都繼承於Object基礎類別的Throwble類別。1.Error類別:執行程式發生嚴重的錯誤,造成程式很難復原時,會自動拋出的例外處理,撰寫程式碼時,不可以拋出這個類別的例外 處 理。常 見 的 子 類 別 有 Li
5、nkageError、ThreadDeath與VirtualMachineError等,最典型的錯誤情況就是耗盡記憶體,事實上是無法復原程式的。2.Exception類別:包含一般情況下會發生的例外處理。當發生這類型的錯誤時,只要在程式碼中拋出例外處理,就可以解決問題,常 見 的 類 別 有 IOException(檔 案 處 理 的 例 外 類 別)與RuntimeException。3.RuntimeException類別:程式執行時期會發生的例外處理。這類型的例外錯誤是程式本身設計的問題,所以即使沒有在程式碼拋出這類型的例外處理,程式仍然可以編譯成功,等到執行程式時才會發生錯誤。13下面
6、是RuntimeException類別中常用的例外處理類別說明:1410-1.3建立例外處理n在10-1.2小節中,例外處理機制會於第(1)和(2)類程式碼發生錯誤時,中斷程式碼的執行。n但在執行階段出現錯誤時,例如需要由使用者輸入資料、存取檔案或是透過網路傳遞訊息等情況時,雖然程式碼中沒有任何錯誤,但執行時仍然可能發生錯誤,下面將說明處理錯誤的方式。15利用判斷式:n俗語說:未雨綢繆,意指在事情尚未發生前,預先做好準備,妥善安排要如何處理。n在設計程式時,也應該先想好各種突發狀況的解決方法,要避免發生這類的錯誤,可以撰寫判斷式來處理,例如下面的程式碼:16n上述程式碼第5行的除數b不得為0,
7、所以在第69行加入if判斷式,處理當除數等於0時,要傳送的錯誤訊息。17完成後,執行程式的畫面顯示如下:18利用例外處理機制:n雖然可以利用判斷式來處理錯誤狀況,但是當程式較龐大時,例如要輸入多次資料、開啟多次檔案等,每執行一次就必須呼叫一次判斷式,這樣似乎太麻煩了,而且防不勝防,最簡單的方式就是在程式中建立例外處理機制。19定義例外處理機制的語法如下:20上述語法說明如下-1:1.try區塊中的程式碼會被檢查是否發生例外狀況,捕捉到例外。若是,就會執行與“例外類別”型別符合的catch區塊(相同的例外類別或該例外類別的基礎類別);若不是,就會直接跳到finally區塊執行。2.catch區塊
8、是發生例外狀況時要執行的程式碼,可以有一到多個例外狀況。因為每個catch區塊是獨立分開的,所以傳遞的“例外參數”通常會 統 一 命 名 為“e”,例 如:ArithmeticException e、IndexOutOfBoundsException e。21上述語法說明如下-2:3.finally區塊可以省略,無論前面有沒有符合例外參數型別的catch區塊,都會執行此區塊。4.執行完trycatchfinally區塊後,會繼續執行trycatchfinally區塊後面的程式碼。5.因為Throwable類別是Java所有例外類別的基礎類別,例外參數e可以存取下面幾個Throwable類別的成
9、員函式:22例如下面的程式碼:23上述程式碼分析如下:1.第614行利用trycatch敘述建立例外處理。2.在try區塊中會判斷第7行的敘述是否發生例外狀況,因為捕捉到一個ArithmeticException類別的例外,所以會執行第9行。3.當執行完catch區塊的程式碼後,會執行finally區塊的程式碼。24完成後,執行程式的畫面顯示如下:25由上面的範例中可以將例外處理的優點整理如下:1.當程式中發生錯誤時,只要將例外參數丟出給catch區塊處理即可。2.發生錯誤時,每一種例外狀況會執行對應的錯誤處理方式,相當清楚。262710-1.4同時處理多個例外狀況n在前一小節的例外處理機制中
10、,catch區塊僅捕捉一種錯誤情況的例外,若發生其他例外情況,則會出現錯誤訊息,同時中斷程式的執行。28下面的程式碼,先判斷陣列的索引值是否超出範圍,再顯示陣列內容:n只要在程式中加入多個catch區塊,就可以同時處理多個例外情況,例如下面的程式碼,先判斷陣列的索引值是否超出範圍,再顯示陣列內容:2930上述程式碼分析如下:1.第825行利用trycatch敘述建立例外處理,以判斷輸入的資料筆數是否會發生錯誤。2.在try區塊中會判斷第914行的敘述是否發生例外狀況。3.若捕捉到一個ArithmeticException例外類別的錯誤,就執行第17行;若捕捉到一個IndexOutOfBound
11、sException例外類別的錯誤,就執行第21行;若捕捉到一個Exception例外類別的錯誤,就會執行第24行。4.從程式碼中可以發現Exception是IndexOutOfBoundsException的基礎類別,所以當陣列大小溢位時,兩個類別都可以捕捉此例外錯誤,此 時 Java會 先 採 用 層 級 較 低 的 衍 生 類 別IndexOutOfBoundsException,必須要將該類別的catch區塊撰寫在Exception類別的catch區塊前面,否則兩個catch區塊都符合這個例外情況,會造成編譯錯誤。5.利用trycatch敘述檢查錯誤後,會繼續執行trycatch敘述外
12、面第27行的程式碼。31完成後,執行程式的畫面顯示如下:n若 輸 入 筆 數 不 等 於 整 數,則 會 發 生NumberFormatException例外錯誤,但因為程式中沒有NumberFormatException例外類別的catch區塊,所以會執行基礎類別Exception的catch區塊。3210-2拋出例外n10-2.1在程式中拋出例外n10-2.2在函式中拋出例外 n10-2.3在函式參數列後面拋出例外n10-2.4巢狀例外33前言:n除了捕捉Java拋出的例外,在Java中,可以利用關鍵字throw自行拋出例外。n除此之外,也可以利用關鍵字throws在指定的函式中拋出例外。
13、3410-2.1在程式中拋出例外n雖然在Java中可以利用trycatch區塊捕捉例外情況,但難免會出現利用例外處理仍然抓不到的錯誤。前面在範例檔ch10_01_03b曾經捕捉整數除法中除數為0的運算式,而利用trycatch區塊可以捕捉成功。n但如果將整數皆修改為浮點數,則捕捉不到例外 情 況,計 算 出 來 的 商 為 Infinity,也就是無限小數,這是因為Java允許除數為浮點數0.0,所以不會產生錯誤。35例如下面的程式碼:n上述程式碼第13行利用getMessage函式取得發生例外情況的錯誤訊息,在此為Java內建的錯誤訊息“/by zero”。36完成後,畫面顯示如下:n完成後
14、執行程式,計算浮點數5.0/0.0的結果為Infinity,並沒有捕捉例外;而計算整數5/0時,則捕捉到一個ArithmeticException例外,錯誤訊息為“/by zero”,畫面顯示如下:37拋出例外時必須同時建立一個例外物件,其語法如下:n上面的程式碼看似沒有問題,其實除數為浮點數0.0是不合法的,此時就可以自訂例外的判斷規則,在程式中拋出例外。n上述語法的“例外參數”可以省略,此參數表示該例外變數的getMessage成員函式值,也就是例外的錯誤訊息,若在程式中拋出例外,則例 外 參 數 的 值 會 覆 蓋 原 本 Java內 建 的getMessage函式值。38下面程式碼將範
15、例檔ch10_02_01a修改為利用關鍵字throw拋出例外的方式:3940上述程式碼分析如下:1.第812行利用ifelse敘述建立例外處理,判斷當浮點數除數為0的時候,就拋出一個ArithmeticException例外處理,並設定顯示的錯誤訊息為“除數為0”。2.當拋出ArithmeticException例外處理時,會執行第1619行的catch區塊,在此錯誤訊息為自訂的“除數為0”。41完成後,執行程式的畫面顯示如下:4210-2.2在函式中拋出例外n上面的範例是在trycatch敘述中拋出例外狀況,但如果程式中有很多種例外狀況,就會讓trycatch敘述看起來繁雜又冗長,此時可以將
16、throw敘述以函式取代,在函式中拋出例外。n範例檔ch10_01_04雖然可以判斷陣列索引值是否超過陣列大小,但是當使用者輸入的陣列筆數小於或等於0時,程式卻無法判斷出錯誤,因此可以自訂函式拋出例外,例如下面的程式碼:434445上述程式碼分析如下:1.第2530行在check_size函式中判斷當n10時,皆拋出IndexOutOfBoundsException例外,並設定不同的例外參數。2.第11行在使用者輸入資料筆數後,呼叫check_size函式檢查是否正確。3.當使用者輸入資料的資料型別不符合時,會執 行 第 2022行 的 catch區 塊,捕 捉NumberFormatExce
17、ption例外類別的錯誤情況。46完成後,執行程式的畫面顯示如下:474810-2.3在函式參數列後面拋出例外n假 設 在 函 式 中 發 生 IOException或ClassNotFoundException等例外情況,但是函式中並沒有撰寫trycatchfinally區塊來捕捉這些例外時,則因為這些例外類別不屬於RuntimeException類別,因此編譯程式時就會發生錯誤。n此時,可以直接在宣告函式時,利用關鍵字throws在參數列後面拋出例外,其語法如下:49上述利用關鍵字throws在參數列後面拋出例外的語法說明如下:n上述語法可以拋出一個或多個例外,如果要拋出多個例外,必須以逗
18、點,隔開每個例外類別名稱,例如前面介紹很多需要輸入資料的程式,都必須在main()方法參數列的後面拋出一個IOException例外類別。50下面將輸入資料的動作另外撰寫在一個函式中,其程式碼如下:n下面的程式碼將輸入資料的動作另外撰寫在一個函式中,則除了main()方法以外,該函式參數列的後面也要拋出IOException例外類別:5152上述程式碼分析如下:1.第1823行宣告input函式,因為函式中提供輸入資料,並且拋出一個ClassNotFoundException例外,而函式中沒有撰寫trycatchfinally區塊來捕捉這些例外,所以要在參數列後面拋出這些例外。2.第 514行
19、 在 main()方 法 中 必 須 利 用trycatch區塊來捕捉例外。3.第6行的try區塊中呼叫input函式,以檢查輸入的資料是否有錯誤。53完成後,執行程式的畫面顯示如下:5410-2.4巢狀例外n例外處理與迴圈一樣,可以有好多層,外層的try區塊中又包含內層的trycatch敘述,而每一層的throw敘述會執行對應該層的catch區塊,稱為巢狀例外。55定義巢狀例外的語法如下:56例如求指數值的規則如下(b為底數,e為指數):57利用巢狀例外可以判斷求指數值時會發生的錯誤,程式碼如下:585960上述程式碼分析如下:1.第1023行是外層的trycatch敘述,第1421行是內層
20、的trycatch敘述。2.第12行拋出例外時,會跳過第1421行,直接由第2426行的外層catch區塊來處理。3.第16行拋出例外時,會由第1821行的內層catch區塊來處理。4.第20行利用return敘述,強制結束程式。61完成後,執行程式的畫面顯示如下:626310-3自訂例外類別n除了使用Java內建的例外類別以外,如果在程式除錯時,找不到適當的例外類別,則可以自行定義需要的例外類別,以協助程式的除錯工作。n因為Java的例外類別主要繼承自Exception基礎類別,所以自訂例外類別時,統一都是繼承於Exception基礎類別,其語法如下:n自訂例外類別後,可以繼承原來Excep
21、tion基礎類別中的成員,也可以在程式敘述區塊中另外撰寫程式碼,覆載基礎類別中的建構式與成員函式。64例如下面的程式碼:6566上述程式碼分析如下:1.第2429行自訂例外類別GradeException,繼承於Exception基礎類別。2.第2628行覆載Exception類別中的getMessage成員函式,重新定義getMessage函式的內容,回傳新的字串。3.第720行撰寫trycatch敘述,判斷是否要拋出例外。4.第14行表示如果輸入的成績不介於0100之間,就拋出使用者自訂的GradeException例外。5.第 1720行 的 catch區 塊 表 示,當 捕 捉 到GradeException例外時,就顯示例外處理的記錄訊息。67完成後,執行程式的畫面顯示如下:68溫故知新-1:69溫故知新-2:70溫故知新-3:71自我突破習題-選擇題:72自我突破習題-選擇題:73自我突破習題-選擇題:74自我突破習題-實作題:75自我突破習題-實作題:76自我突破習題-實作題:77
限制150内