《Java語言程序設計案例教程》課件第7章_第1頁
《Java語言程序設計案例教程》課件第7章_第2頁
《Java語言程序設計案例教程》課件第7章_第3頁
《Java語言程序設計案例教程》課件第7章_第4頁
《Java語言程序設計案例教程》課件第7章_第5頁
已閱讀5頁,還剩82頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第7章異常處理7.1異常處理7.2用戶自定義異常類第7章異常處理學習目標

掌握Java語言中異常的概念;

了解異常的處理機制;

了解Java語言中的異常類;

掌握try、catch和finally語句的用法;

學會自定義異常類。程序設計屬于邏輯思維的范疇,即使是一個非常有經驗的程序員,也難免會出現編程錯誤。因此,為了使程序即使在有“問題”的時候也能正常運行,往往要耗費程序設計人員很大的精力。Java語言為軟件開發(fā)人員提供了一種非常方便與有效的異常處理機制,利用這種機制可以將程序的功能代碼與異常處理代碼有效分開,使程序結構清晰,易于維護。本章介紹Java語言中異常處理的概念、異常的處理機制和設計異常處理類的方法。7.1異常處理在第1章調試Java程序的基本技能中介紹過,程序中的錯誤可分為三類:編譯錯誤、運行時錯誤和邏輯錯誤。編譯錯誤是由于沒有遵循Java語言的語法規(guī)則而產生的,這種錯誤要在編譯階段排除,否則程序無法運行。發(fā)生邏輯錯誤時,程序編譯正常,也能運行,但結果不是人們所期待的。舉一個簡單的例子來說,如果程序要求a與b兩個數的和,但因表達式寫錯,而求出的結果是a與b兩個數的差。對于程序邏輯上的這種錯誤,要靠程序員對程序中的邏輯進行仔細分析來加以排除。而運行時錯誤是指程序運行過程中出現了一個不可能執(zhí)行的操作。運行時錯誤有時也可以由邏輯錯誤引起。異常處理的主要目的是,即使在程序運行時發(fā)生了錯誤,也要保證程序能正常結束,避免因錯誤而使正在運行的程序中途停止。7.1.1異常的有關概念與異常處理機制

1.異常程序運行過程中出現的非正常情況通常有兩類:●錯誤(Error):是致命性的,如程序運行過程中內存不足等,這種嚴重的不正常狀態(tài)不能恢復執(zhí)行?!癞惓?Exception):是非致命性的,如數組下標越界、表達式的分母為0等。這種不正常狀態(tài)可通過恰當的編程而使程序繼續(xù)運行。異常有時也稱為例外。致命性的錯誤一般很少出現,即使出現了這類錯誤,在程序中也不進行處理。一般程序中需要處理的主要是非致命性錯誤,即異常。那么一個程序出現異常情況時,會有什么現象呢?看下面一個簡單的實例程序:1publicclassZero{2 publicstaticvoidmain(String[]args){3 System.out.println(10/0);4 System.out.println("程序運行結束!");5 }6}該程序的第3行要求“10/0”表達式的結果,由于分母為0,因而該式無法正常運算。程序執(zhí)行后輸出如下結果:Exceptioninthread"main"java.lang.ArithmeticException:/byzero

atZero.main(Zero.java:3)由于程序中沒有處理異常情況的代碼,因此當程序出現異常時將終止執(zhí)行,同時系統(tǒng)自動輸出一條有關此異常的描述信息。注意,該程序的第4行前已經出現了錯誤,所以第4行輸出字符串的語句將永遠得不到執(zhí)行。上面輸出的第1行信息說明,在main方法中出現了類型為“java.lang.ArithmeticException”的異常(表示一個算術運算異常),異常的原因為“/byzero”,即用0做除數。第2行表示調用Zero.main方法時產生了異常(在程序Zero.java的第3行)。以上異常的傳統(tǒng)糾正方法是在進行除法運算之前,先判斷除數是否為0,然后根據判斷情況進行適當的處理。如果一個程序有很多這樣的處理代碼,則會使程序的處理邏輯顯得雜亂無章,甚至會引入一些其他錯誤。如果使用Java的異常處理機制,則可以將異常處理代碼從程序中分離出來,并可以將異常根據情況進行分類,對不同的異常集中編寫相應的處理程序,從而保證了程序的安全性。

2.?Java語言中處理異常的機制作為一種面向對象的程序設計語言,Java語言中的異常與其他語言要素一樣,也是用對象來表示的。

Java語言的設計者將Java語言程序中可能出現的各種錯誤與異常進行了歸納與總結,并將歸納與總結的結果定義成了一個個表示錯誤與異常的類。每個類代表了一種運行錯誤,類中包含了代表該運行錯誤的信息和處理錯誤的方法等。在Java程序的運行過程中,如果發(fā)生了一個運行錯誤,則當系統(tǒng)識別到這個運行錯誤正好與已經定義好的某個異常類相對應時,系統(tǒng)就會自動生成一個與該異常類對應的實例對象(其中包含了該異常事件的類型和異常發(fā)生時程序的運行狀態(tài)),這時我們就說系統(tǒng)產生了一個異常。一旦在執(zhí)行某個方法時產生了一個異常類對象,運行時系統(tǒng)就在該方法中查找異常處理程序,如果沒有找到,就查找調用了該方法的方法中是否有異常處理程序,這樣一直找下去,直到找到異常處理程序為止。這樣就可以確保不會發(fā)生死機、程序運行中斷等情況。下面介紹Java語言中預定義的異常類及其類的層次結構。

3.異常類在Java編程語言中,異常類及其子類的層次結構如圖7-1所示。從圖7-1中可以看出,Throwable類是Java語言中所有錯誤或異常的超類,只有當對象是此類(或其子類之一)的實例時,才能通過Java虛擬機對其進行異常處理。Throwable類位于java.lang包中,其他大多數定義具體異常的子類均放在各自的功能包中,如輸入/輸出異常類IOException及其子類就位于java.io包中。圖7-1異常類及其子類的層次結構

1)?Throwable類

Throwable類主要用于描述異常發(fā)生的位置和異常的內容,它有Error和Exception兩個基本子類。Throwable類中定義的成員方法均為公共的(public),因此所有異常類都可以使用這些成員方法。Throwable類的常用構造方法是:Throwable(Stringmessage)該構造方法以message的內容作為錯誤信息串(即對錯誤信息的描述)來創(chuàng)建Throwable對象,并記錄異常發(fā)生的位置。

Throwable類定義的常用方法有:●?publicStringgetMessage():本方法返回字符串變量message的內容,該內容是對異常的描述信息?!?publicStringtoString():若當前對象包含錯誤信息,則本方法返回由三部分組成的字符串,即當前對象的類名、一個冒號和一個空格、錯誤信息字符串;若當前對象未包含錯誤信息,則僅返回當前對象的類名?!?publicvoidprintStackTrace():該方法輸出的第一行是當前對象toString()的返回值,其余各行輸出異常發(fā)生的地點和方法調用的順序。

2)?Error類

Error類描述致命性的系統(tǒng)錯誤,如Java的內部錯誤、資源耗盡等情況。這類異常由Java系統(tǒng)直接處理,用戶程序不用理會這類異常。

3)?Exception類程序運行時產生的所有非致命性異常都是Exception類的子類。可以將Exception類的子類分為兩個部分:一部分是RuntimeException類及其子類,稱為非檢查型異常;另外一部分是除RuntimeException類及其子類之外的所有其他類,稱為檢查型異常。

RuntimeException類表示一種程序在設計中出現的問題。如在程序設計時,由于考慮不周而使數組的下標(或稱索引)超出了數組的界限(ArrayIndexOutOfBoundsException),用0做除數(ArithmeticException),引用了一個空值對象變量(NullPointException)等,對于這類運行時異常,如果程序設計過程正確,則該異常是不會出現的,因此編譯器對這類異常在程序中是否進行了處理不進行檢查。下面是一個演示這種異常的實例:01classDemoException{02publicstaticvoidmain(String[]args){03int[]a={2,4};04m1(a); 05System.out.println("執(zhí)行了m1(a)");06}07staticvoidm1(int[]b){08 m2(b);09}10staticvoidm2(int[]c){11System.out.println(c[2]);12}13}程序中沒對異常進行任何處理,程序能正確編譯,但在運行時出現了如下的異常信息:Exceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException:2atDemoException.m2(DemoException.java:11)atDemoException.m1(DemoException.java:8)atDemoException.main(DemoException.java:4)程序的第03行定義了一個有兩個元素的數組。第04行調用了靜態(tài)方法m1,調用m1方法的實參是數組a。第07行的m1方法又調用了第10行定義的m2方法,調用m2方法的實參是數組b,m2方法的第11行輸出數組中下標為2的元素值。由于該數組只有兩個元素,最大下標只能是1,因而程序執(zhí)行時輸出如上的運行時異常信息。該信息表明程序中出現了一個ArrayIndexOutOfBoundsException類的運行時異常,該異常由m2方法的第11行引發(fā)。其方法的調用順序是,在main方法的第4行調用m1方法,在m1方法的第8行調用m2方法。對于非檢查型異常,要求程序員在調試程序時進行詳細分析,并加以排除。程序中對這類異常一般不進行處理(如果需要的話也可以進行處理),而由系統(tǒng)檢測并輸出異常的內容。下面是幾個常見的非檢查型異常類的含義:●?ArithmeticException:在整數進行除法運算時,如果除數為0,就會產生該類異常。例如:inti=10/0;●?NullPointerException:當對象沒被實例化時,訪問對象的屬性或方法就會產生該類異常。例如:

String[]a=newString[2];

//聲明一個包含兩個字符串的數組

System.out.println(a[0].length());

//a[0]字符串還沒有創(chuàng)建,就調用求其長度的方法●?NegativeArraySizeException:創(chuàng)建帶負維數大小的數組時,就會產生該類異常。例如:int[]a=newint[-2];●?ArrayIndexoutofBoundsException:訪問超過數組大小范圍的一個下標元素時,就會產生該類異常。如上面的實例。如果一個方法可能產生除RuntimeException類及其子類之外的其他檢查型異常,則在Java程序編譯時要對這類異常是否進行了處理進行檢查。當編譯器檢查到程序中沒有對這類異常進行處理時,就會產生編譯錯誤。下面介紹Java中對異常進行處理的方法。

4.異常的處理對于檢查型異常,Java要求程序中必須進行處理。具體處理方法有兩種:聲明拋出異常和捕獲異常。

1)聲明拋出異常如果在當前方法中對產生的異常不想進行處理,或者不能確切地知道該如何處理這一異常事件時,可以使用throws子句將異常拋出,交給該方法的調用者進行處理,當然調用者也可以繼續(xù)將該異常拋出。聲明拋出異常是在一個方法聲明中用throws子句指明的。例如:publicintread()throwsjava.io.IOException{

...}表示read方法對IOException異常不進行處理。IOException異常類是Java程序中要輸入或輸出信息時引發(fā)的異常。在throws子句中,同時可以指明多個要拋出的異常,多個異常之間用逗號隔開。例如:publicstaticvoidmain(Stringargs[])throwsjava.io.IOException,IndexOutOfBoundsException{

…}表示main方法拋出IOException和IndexOutOfBoundsException異常。如果在main方法中也選擇了拋出異常,則Java虛擬機將捕獲該異常,在輸出相關異常信息后,中止程序的運行。注意:子類中如果重寫了父類中的方法,則子類方法中可聲明拋出的異常類只能是被重寫方法中throws子句所拋出異常類的子集,也就是說,子類中重寫的方法不能拋出比父類中方法更多的異常。例如:1classFather{2voidf()throwsjava.io.IOException{}3}4classSonextendsFather{5 voidf()throwsException{}6}該程序的子類Son在重寫父類的f方法時,聲明拋出的異常比父類第2行中f方法聲明拋出的異常范圍要大(因為Exception異常類是IOException異常類的父類),所以在編譯該程序時就會產生編譯錯誤。如果將第5行的Exception改為java.io.FileNotFoundException,則程序不會出現編譯錯誤,因為FileNotFoundException(文件沒有找到異常)類是IOException異常類的子類。

2)在方法中捕獲并處理異常在一個程序中,應對異常更積極的方法是將其捕獲并進行處理。在方法中捕獲并處理異常要使用try/catch語句。try/catch語句的語法格式如下:try{//在此區(qū)域內可能發(fā)生異常;}catch(異常類1e1){//處理異常1;}…catch(異常類nen){//處理異常n;}finally{//不論異常是否發(fā)生都要執(zhí)行的部分;}一個try塊后根據需要可以跟一個或多個進行異常處理的catch塊,finally塊是可選的。在設計程序時,要將可能發(fā)生異常的程序代碼放置在try語句塊中,將發(fā)生異常時的處理程序放在catch語句塊中。程序在正常運行過程中,后面的各catch塊不起任何作用。如果try塊內的代碼出現了異常,則系統(tǒng)將終止try塊代碼的執(zhí)行,自動跳轉到與產生異常相匹配的catch塊中,執(zhí)行該塊中的代碼。例如:1try{2c=a/b;3System.out.println("try語句塊執(zhí)行結束");4}5catch(ArithmeticExceptione){6System.out.println("除數為0,a/b的結果無法求出!");7}如果b為0,則try塊中的程序產生ArithmeticException類的異常,第3行的輸出語句不會被執(zhí)行,程序自動轉到第5行所指的catch塊中執(zhí)行異常處理程序。當有多種類型的異常需要捕獲時,一個try塊可以對應多個catch塊。如果一個try塊對應多個catch塊,當try塊中產生異常時,究竟會執(zhí)行哪個catch塊中的異常處理程序呢?這決定于try塊中產生的異常對象能與哪個catch塊中要捕獲的異常類相匹配。如果多個catch塊中要捕獲的異常類有子類與父類的關系,或有子類與祖先類的關系,則catch塊中異常類的順序要放置合理,否則程序在出現異常時,可能不能正確運行。在catch塊中,應將特殊的異常類處理程序(即catch塊)放在前面,將一般的異常類處理程序放在后面。在異常類層次結構樹中(如圖7-1所示),一般的異常類在頂層(圖7-1中靠左邊的類),特殊的異常類在底層(圖7-1中靠右邊的類)。如果一個異常類的順序放置不合理,則該catch塊中的語句可能永遠也不會被執(zhí)行,例如:try{//可以引起異常的程序代碼}catch(Exceptione){//異常處理1}catch(ArithmeticExceptione){//異常處理2}如果在該程序的try塊中產生ArithmeticException類的異常,則首先被第一個catch塊捕獲,因為Exception類是ArithmeticException類的間接父類。正確的順序是將ArithmeticException異常類放在前一個catch塊中。finally語句塊是個可選項,如果包含有finally語句塊,則無論try塊是否產生異常,finally語句塊內的代碼必定被執(zhí)行。由于try塊內的語句在發(fā)生異常時,產生異常之后的代碼不會被執(zhí)行,因此,如果程序中有些語句無論如何均要被執(zhí)行,則可以將這樣的代碼放在finally塊中。7.1.2【案例7-1】用異常處理機制重寫計算器程序

1.案例描述見第3章案例3-4。

2.案例效果案例程序的執(zhí)行效果如圖7-2所示。圖7-2案例7-1的執(zhí)行效果

3.技術分析該案例中,從鍵盤上輸入的運算式可能發(fā)生的錯誤有如下幾種情況:●輸入的表達式不完整,如圖7-2的第1行。一個表達式由兩個操作數和一個運算符組成,程序中這三個部分分別保存到了args[0]、args[1]和args[2],當式子不完整時,使用args[0]、args[1]和args[2]就會出現下標元素越界的異常ArrayIndexOutOfBoundsException?!褫斎氲倪\算數不是整數,如圖7-2的第3行。如果輸入了其他的非整數數據,則在使用Integer.parseInt()方法進行數據格式轉換時就會產生NumberFormatException異常?!褫斎氲谋磉_式中除數為0,如圖7-2的第5行。除數為0時就會產生ArithmeticException異常。●輸入的表達式運算符不正確,如圖7-2的第7行。對于這種情況,系統(tǒng)沒有預定義的異常類,如果發(fā)生了這種情況,則在程序中生成一個異常。所有這些異??梢栽诔绦蛑羞M行統(tǒng)一處理,即將可能產生異常的語句放入try塊中,在其后進行捕獲并處理這些不同的異常。

4.程序解析下面是該案例的程序代碼:01//*********************************************02//案例:7-1程序名:SimpleCal2.java03//功能:簡單的計算器,可以進行兩個整數的加、減、乘、除運算04//*********************************************0506classSimpleCal2{07 //operand1和operand2保存兩個運算數據08 privateintoperand1,operand2;09 //operator保存運算符10 privatecharoperator;11 12 SimpleCal2(){}13 14 //初始化運算式的構造方法15 SimpleCal2(intoperand1,charoperator,intoperand2){16 this.operand1=operand1;17 this.operand2=operand2;18 this.operator=operator;19 }20 21 //求運算結果22 privateintcal()throwsArithmeticException,Exception{23 intresult=Integer.MIN_VALUE;24 if(operator=='+')25 result=operand1+operand2;26 elseif(operator=='-')27 result=operand1-operand2;28 elseif(operator=='*')29 result=operand1*operand2;30 elseif(operator=='/'){31 result=operand1/operand2;32 }33 else{34 thrownewException("輸入的運算符錯誤!");35 } 36 returnresult;37 }38 39 //輸出運算式和運算結果40 publicvoidshowResult()throwsArithmeticException,Exception{41 System.out.println("運算結果:"+operand1+operator+operand2+"="+cal());42 }43 44 publicstaticvoidmain(String[]args){45 intp1,p2;46 try{47 p1=Integer.parseInt(args[0]);48 charop=args[1].charAt(0);49 p2=Integer.parseInt(args[2]);50 SimpleCal2exp=newSimpleCal2(p1,op,p2);51 exp.showResult();52 }53 catch(NumberFormatExceptione1){54 System.out.println("輸入的運算數不是整數!");55 }56 catch(ArrayIndexOutOfBoundsExceptione2){57 System.out.println("輸入的運算式不完整!");58 }59 catch(ArithmeticExceptione3){60 System.out.println(“除數為0,不能進行除法運算!");61 }62 catch(Exceptione4){63 e4.printStackTrace();64 }65 }66}該程序第22行定義的cal()方法,在進行算術運算時如果除數為0,則可能產生ArithmeticException類的算術運算異常。用cal()方法進行運算時,如果運算符不是所要求的運算符,則第34行在程序中主動生成并拋出一個Exception類的異常,由thrownewException("輸入的運算符錯誤!")語句完成該功能(該知識點下面介紹),異常信息為Exception構造方法中參數所給的內容。對cal()方法中產生的這兩種異常并沒有進行捕獲與處理,所以在cal()方法中聲明拋出這兩種異常,由調用該方法的程序進行處理。在第40行定義的showResult()方法體中調用了cal()方法,因此,在該方法中應該處理由cal()方法聲明拋出的異常。但該方法也沒有進行異常捕獲與處理,而是將這兩種異常繼續(xù)聲明拋出“throwsArithmeticException,Exception”。在主方法main中調用了showResult()方法,因此對于showResult()方法聲明拋出的異常一定要進行處理,如果不進行處理,則只能在發(fā)生異常時中斷程序的運行。在main方法中,將可能產生異常的語句放入了第46~52行的try塊中,第53~64行是對各種異常的處理程序。第63行調用異常類printStackTrace()方法輸出異常發(fā)生的信息和方法調用的先后次序。注意,一定要將Exception異常的處理語句放在catch塊的最后,否則其他的異常將無法被捕獲。7.1.3【相關知識】用戶創(chuàng)建并拋出系統(tǒng)預定義異常在一個程序中產生并拋出異常有兩種情況:一是當程序中產生了一個系統(tǒng)可以識別的、預定義的異常類時,由虛擬機生成并拋出異常對象,如ArithmeticException、ArrayIndexOutOfBoundsException等異常類;另一種情況是在程序中主動產生一個異常對象(而非系統(tǒng)產生),然后使用throw語句拋出該異常對象,在方法中對這類異常也要進行捕獲并處理。例如案例7-1程序代碼的第34行。又如:IOExceptione=newIOException();throwe;要注意,可以拋出的異常必須是Throwable類或其子類的實例。技能拓展7.2用戶自定義異常類在程序中除了經常用到的系統(tǒng)預定義異常類,如用0作除數、下標越界、數據格式錯誤、輸入/輸出錯誤等異常外,在具體開發(fā)一個軟件時還可能會用到系統(tǒng)中沒有定義的異常,如成績管理軟件中學生的成績只能在0~100分之間(假如使用百分制計成績),如果超過這個范圍,則成績數據肯定有誤。對于這種情況,程序員可以根據實際需要自己設計異常類。7.2.1設計異常類

1.自定義異常類的格式在Java程序設計中,程序員可以自己定義一些異常類,稱之為用戶自定義異常類。用戶自定義的異常類必須繼承自Throwable類或其子類,比較常用的是繼承Exception類。其一般格式為class自定義異常類名extendsException{//異常類體;}自定義異常類如果繼承了異常類Exception,則Java就會將自定義的異常類視為檢查型異常。在一個方法中如果有這類異常產生,就一定要聲明拋出(throws),讓該方法的調用者處理,或者在該方法中直接捕獲并處理,否則程序在編譯時就會產生錯誤,提示用戶沒有聲明或處理異常。下面的示例定義了一個簡單的自定義異常類:1classMyExceptionextendsException{2 MyException(){3 }4 5 MyException(Stringmsg){6 super(msg);7 }8}程序的第2行定義了一個無參的構造方法,第5行定義了帶一個字符串參數的構造方法,該方法在第6行調用了父類帶一個參數的構造方法。在自定義的異常類中,一般要聲明兩個構造方法:一個是不帶參數的構造方法;另一個是以字符串為參數的構造方法。帶字符串參數的構造方法以該字符串參數表示對異常內容的描述,如果使用getMessage()方法,則可以返回該字符串。由于自定義異常類繼承了Exception類,也就擁有了Throwable類的除構造方法以外的其它方法,因此在本章第1節(jié)中介紹的Throwable類中定義的方法都可以在自定義異常類中使用。

2.創(chuàng)建與拋出自定義異常如果程序中發(fā)生了系統(tǒng)預定義的異常類,則Java虛擬機會自動生成并拋出該異常類的對象。而用戶自定義異常則要由用戶在程序中根據具體情況創(chuàng)建并拋出,才可以在程序中進行捕獲和處理。自定義異常的創(chuàng)建就是使用已定義好的異常類生成該類的一個實例。例如對于MyException異常類,可以使用如下的語句創(chuàng)建一個該類的異常:MyExceptione=newMyException("這是自定義的一個異常類實例");創(chuàng)建好的異常類對象,只有拋出后才可以被程序捕獲。拋出創(chuàng)建的異常e時,要使用throw語句:throwe;如果要拋出的異常只被使用一次,則可以將以上兩步用如下的簡單格式書寫:thrownewMyException("這是自定義的一個異常類實例");7.2.2【案例7-2】統(tǒng)計學生成績分布情況

1.案例描述設計一個程序,從鍵盤上輸入學生的成績,然后統(tǒng)計學生成績的分布情況。要求統(tǒng)計出0~9分,10~19分,20~29分,…,90~99分,100分各區(qū)段的成績個數。

2.案例效果案例7-2的部分執(zhí)行結果如圖7-3所示。第7行的字母“n”表示結束成績的錄入過程。圖7-3案例7-2的執(zhí)行結果

3.技術分析如果從鍵盤上輸入的學生成績小于0或者大于100分,就認為是異常的成績。程序中若遇到異常成績,該如何處理呢?在沒有學習異常處理知識之前,我們只能對成績判別后分情況進行處理,程序結構比較混亂。在本案例中,我們可以單獨設計一個表示學生成績異常的類(ScoreException),如果遇到成績小于0或者大于100分的情況,則生成并拋出一個異常,然后在異常處理程序塊(即catch塊)中單獨進行處理。

4.程序解析下面是案例7-2的程序代碼:01//********************************************02//案例:7-2程序名:TestScoreException.java03//功能:統(tǒng)計學生的成績分布情況04//*********************************************0506importjava.util.Scanner;0708classScoreExceptionextendsException{09 privateintscore;10 11 publicScoreException(){}12 13 publicScoreException(Stringmsg,intscore){14 super(msg);15 this.score=score;16 }17 18 publicStringtoString(){19 if(score<0)20 returngetMessage()+":輸入的成績是負數。";21 else22returngetMessage()+":不能輸入大于100分的成績。";23 }24}2526classTestScoreException{27 publicstaticvoidmain(String[]args){28 int[]s=newint[11];29 input(s);30 print(s);31 }32 33 //輸出成績分布情況34 staticvoidprint(int[]s){35 System.out.println("\n學生成績分布情況如下:");36 for(inti=0;i<s.length;i++){37 if(i<10)38 System.out.print(i*10+"~"+(i*10+9)+":");39 else40 System.out.print(i*10+":");41 for(intk=0;k<s[i];k++){42 System.out.print("*");43 }44 System.out.println();45 } 46 }47 48 //錄入成績,并將各區(qū)段學生的人數存放在數組s中49 staticvoidinput(int[]s){50 Scannersc=newScanner(System.in);51 inttemp;52 System.out.println(“請輸入成績后回車,結束輸入時按非數字鍵!");53 while(sc.hasNextInt()){54 55 try{56temp=sc.nextInt();57if((temp>100)||(temp<0))58thrownewScoreException("成績格式不正確",temp);59 s[temp/10]++;60 }61 catch(ScoreExceptione1){62 System.out.println(e1);63 }64 }65 }66}在程序中要使用Scanner類的實例輸入成績,第06行引入java.util包中的Scanner類。第08~24行定義了一個用戶異常類ScoreException,該類繼承了Exception異常類。在ScoreException類中定義了一個私有數據成員和兩個構造方法。數據成員score中存放學生的成績信息(其實該成績是一個不在0~100范圍的非法成績)。兩個構造方法中,一個是無參的構造方法,另一個是帶兩個參數的構造方法。在帶兩個參數的構造方法中,第1個參數是對異常的描述,第2個參數是錄入的成績。第14行調用了父類帶一個參數的構造方法。第18行重寫了父類的toString方法,在第62行的輸出中,參數使用ScoreException類的一個對象名時,會自動調用該方法。第26~66行定義了TestScoreException類,該類的功能是輸入成績,并統(tǒng)計各區(qū)段的成績個數。第28行定義的整型數組s共有11個下標變量,這11個下標變量與0~9分,10~19分,20~29分,…,90~99分,100分共11個分數段對應,分別用于存放各區(qū)段的分數個數。第29行調用input方法輸入學生成績,并將各區(qū)段成績的個數存入參數數組s中。第30行調用print方法將參數s數組進行輸出。在第49~65行定義的input方式中,第50行創(chuàng)建了一個Scanner類的實例sc,使用“System.in”作構造方法的參數,表示要從鍵盤上輸入數據,第53行調用Scanner類中定義的hasNextInt方法,該方法表示輸入信息中的下一個標記可以解釋為整數時,hasNextInt方法返回true,只要輸入一個非整數的值,hasNextInt方法就返回false,該程序就是利用hasNextInt方法的這個特點來控制成績輸入的。當最后一個成績輸入完成后,只要按鍵盤上的任一個字母鍵后回車,則成績的輸入過程結束(在圖7-3中按下了字母n)。第56行通過sc.nextInt()方法取得從鍵盤輸入的一個整數,經過第57行判別后,如果輸入的成績不在0~100之間,則第58行創(chuàng)建一個自定義異常類ScoreException的實例,構造方法的第1個參數“成績格式不正確”是對異常的描述信息,第2個參數temp是錄入的成績。在異常類ScoreException中定義一個成績字段的原因,是在toString方法中要根據非法成績是負數還是大于100的數生成返回的異常描述信息,見第19行至22行。7.2.3【相關知識】finally之后的程序段是否可以被執(zhí)行的討論在finally塊之后的語句在一般情況下都會被執(zhí)行。在一些特殊情況下,雖然finally塊中的語句可以正常執(zhí)行,但在finally塊之后的語句可能永遠也執(zhí)行不了。下面舉例說明。

1.在catch塊產生了異常,但沒有被捕獲與處理看下面的示例程序:01classDemoException{02publicstaticvoidmain(String[]args){03int[]a={2,4};04try{05 a[2]=1;06System.out.println("tryblock.");07}08catch(Exceptione){09System.out.println("catchblock.");10a[0]=1/0;11}12finally{13System.out.println("finallyblock.");14}15System.out.println("out.");16}17}該程序執(zhí)行后的結果為:catchblock.finallyblock.Exceptioninthread"main"java.lang.ArithmeticException:/byzeroatDemoException.main(DemoException.java:10)程序中finally塊之后的第15行語句沒有被執(zhí)行。這種情況是由于在catch塊中的第10行產生了一個分母為0的異常,但并沒有在該catch塊中對該異常進行捕獲與處理,因此將中斷main方法的執(zhí)行。注意,該程序中try塊中的第06行也沒有被執(zhí)行。要避免這種情況的發(fā)生,可以在catch塊中嵌套try-catch語句,將catch塊中產生的異常也捕獲,并進行處理。

2.?try塊中產生的異常,沒有相應的catch塊捕獲看下面的示例程序:01classDemoException2{02publics

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論