Java面向?qū)ο蟪绦蛟O(shè)計(jì)(IDEA版) 課件 第9章異常處理_第1頁(yè)
Java面向?qū)ο蟪绦蛟O(shè)計(jì)(IDEA版) 課件 第9章異常處理_第2頁(yè)
Java面向?qū)ο蟪绦蛟O(shè)計(jì)(IDEA版) 課件 第9章異常處理_第3頁(yè)
Java面向?qū)ο蟪绦蛟O(shè)計(jì)(IDEA版) 課件 第9章異常處理_第4頁(yè)
Java面向?qū)ο蟪绦蛟O(shè)計(jì)(IDEA版) 課件 第9章異常處理_第5頁(yè)
已閱讀5頁(yè),還剩50頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

面向?qū)ο蟪绦蛟O(shè)計(jì)第9章異常處理

1異常與異常類(lèi)23主要內(nèi)容面向?qū)ο蟪绦蛟O(shè)計(jì)(Java語(yǔ)言描述微課版基于IntelliJIDEA)捕獲異常捕獲多個(gè)異常45throws短語(yǔ)和throw語(yǔ)句try-with-resources語(yǔ)句6自定義異常類(lèi)7斷言8案例:數(shù)組不匹配異常面向?qū)ο蟪绦蛟O(shè)計(jì)9.1異常與異常類(lèi)程序運(yùn)行不可避免會(huì)產(chǎn)生錯(cuò)誤。Java語(yǔ)言提供了健壯的錯(cuò)誤處理機(jī)制,即異常處理。同大多數(shù)現(xiàn)代編程語(yǔ)言一樣,Java語(yǔ)言有著健壯的異常處理機(jī)制。本節(jié)首先討論異常和異常類(lèi),下一節(jié)討論如何處理異常。概述所謂異常(exception)是在程序運(yùn)行過(guò)程中產(chǎn)生的使程序終止正常運(yùn)行的錯(cuò)誤對(duì)象。如數(shù)組下標(biāo)越界、整數(shù)除法中零作除數(shù)、文件找不到等都可能使程序終止運(yùn)行9.1.1異常的概念為了理解異常的概念,首先看下面的代碼。Stringname=null;System.out.println(name.length());該段代碼編譯不會(huì)發(fā)生錯(cuò)誤,但運(yùn)行時(shí)控制臺(tái)輸出如下:Exceptioninthread"main"java.lang.NullPointerExceptionatExceptionDemo.main(ExceptionDemo.java:4)該輸出內(nèi)容說(shuō)明程序發(fā)生了異常,第一行給出了異常名稱(chēng),第二行給出了異常發(fā)生的位置。9.1.1異常的概念Java語(yǔ)言規(guī)定當(dāng)某個(gè)對(duì)象的引用為null時(shí),調(diào)用該對(duì)象的方法或使用對(duì)象時(shí)就會(huì)產(chǎn)生NullPointerException異常,它稱(chēng)為空指針異常。packagecom.boda.xy;publicclassInputChar{publicstaticvoidmain(String[]args){System.out.print("請(qǐng)輸入一個(gè)字符:");charc=(char)System.in.read();//該行發(fā)生編譯錯(cuò)誤System.out.println("c="+c);}}含義是:未處理的IOException類(lèi)型異常程序9.1InputChar.javaJava語(yǔ)言定義了多種異常類(lèi)。都是java.lang.Throwable類(lèi)的子類(lèi),它是Object類(lèi)的直接子類(lèi)。Throwable類(lèi)有兩個(gè)子類(lèi),一個(gè)是Error類(lèi),另一個(gè)是Exception類(lèi),這兩個(gè)子類(lèi)又分別有若干個(gè)子類(lèi)。圖10-1給出了Throwable類(lèi)及其常見(jiàn)子類(lèi)的層次結(jié)構(gòu)。9.1.2異常類(lèi)非檢查異常(uncheckedexception)是RuntimeException類(lèi)及其子類(lèi)異常,也稱(chēng)為運(yùn)行時(shí)異常。常見(jiàn)的非檢查異常如圖10-2所示。1.非檢查異常非檢查異常是在程序運(yùn)行時(shí)檢測(cè)到的,可能發(fā)生在程序的任何地方且數(shù)量較大,因此編譯器不對(duì)非檢查異常(包括Error類(lèi)的子類(lèi))處理,這種異常又稱(chēng)免檢異常。1.非檢查異常程序運(yùn)行時(shí)發(fā)生非檢查異常時(shí)運(yùn)行時(shí)系統(tǒng)會(huì)把異常對(duì)象交給默認(rèn)的異常處理程序,在控制臺(tái)顯示異常的內(nèi)容及發(fā)生異常的位置。下面介紹幾種常見(jiàn)的運(yùn)行時(shí)異常。(1)NullPointerException:空指針異常,即當(dāng)某個(gè)對(duì)象的引用為null時(shí)調(diào)用該對(duì)象的方法或使用對(duì)象時(shí)就會(huì)產(chǎn)生該異常,如:Stringname=null;System.out.println(name.length());//該語(yǔ)句發(fā)生異常1.非檢查異常(2)ArithmeticException:算術(shù)異常,在做整數(shù)的除法或整數(shù)求余運(yùn)算時(shí)可能產(chǎn)生的異常,它是在除數(shù)為零時(shí)產(chǎn)生的異常。inta=5;intb=a/0;//該語(yǔ)句發(fā)生異常注意:浮點(diǎn)數(shù)除法運(yùn)算不會(huì)產(chǎn)生該類(lèi)異常。如,1.0/0.0的結(jié)果為Infinity。1.非檢查異常(3)ClassCastException:對(duì)象轉(zhuǎn)換異常,Java支持對(duì)象類(lèi)型轉(zhuǎn)換,若不符合轉(zhuǎn)換的規(guī)定,則產(chǎn)生類(lèi)轉(zhuǎn)換異常,例如:Objecto=newObject();Strings=(String)o;//該語(yǔ)句發(fā)生異常1.非檢查異常(4)ArrayIndexOutOfBoundsException:數(shù)組下標(biāo)越界異常,當(dāng)引用數(shù)組元素的下標(biāo)超出范圍時(shí)產(chǎn)生的異常,例如:inta[]=newint[5];a[5]=10;//該語(yǔ)句發(fā)生異常因?yàn)槎x的數(shù)組a的長(zhǎng)度為5,不存在a[5]這個(gè)元素,因此發(fā)生數(shù)組下標(biāo)越界異常。1.非檢查異常(5)NumberFormatException:數(shù)字格式錯(cuò)誤異常,在將字符串轉(zhuǎn)換為數(shù)值時(shí),如果字符串不能正確轉(zhuǎn)換成數(shù)值則產(chǎn)生該異常,例如:doubled=Double.parseDouble("5m7.8");//該語(yǔ)句發(fā)生異常該語(yǔ)句產(chǎn)生異常的原因是,字符串"5m7.8"不能正確轉(zhuǎn)換成double型數(shù)據(jù)。1.非檢查異常檢查異常(checkedexception)是除RuntimeException類(lèi)及其子類(lèi)以外的異常類(lèi),有時(shí)也稱(chēng)為必檢異?;蚍沁\(yùn)行時(shí)異常。對(duì)這類(lèi)異常,程序必須捕獲或聲明拋出,否則編譯不能通過(guò)。2.檢查異常程序10.1中的read()方法聲明拋出IOException異常就是檢查異常。再比如,若試圖使用Java命令運(yùn)行一個(gè)不存在的類(lèi),則會(huì)產(chǎn)生ClassNotFoundException異常,若調(diào)用了一個(gè)不存在的方法,則會(huì)產(chǎn)生NoSuchMethodException異常。面向?qū)ο蟪绦蛟O(shè)計(jì)9.2捕獲異常異常處理可分為下面幾種:使用try-catch-finally捕獲并處理異常;通過(guò)throws子句聲明拋出異常;用throw語(yǔ)句拋出異常;使用try-with-resources管理資源。概述異常都是在方法中產(chǎn)生的。方法運(yùn)行過(guò)程中如果產(chǎn)生了異常,在這個(gè)方法中就生成一個(gè)代表該異常類(lèi)的對(duì)象,并把它交給運(yùn)行時(shí)系統(tǒng),運(yùn)行時(shí)系統(tǒng)尋找相應(yīng)的代碼來(lái)處理該異常。這個(gè)過(guò)程稱(chēng)為拋出異常。運(yùn)行時(shí)系統(tǒng)在方法的調(diào)用棧中查找,從產(chǎn)生異常的方法開(kāi)始進(jìn)行回溯,直到找到包含相應(yīng)異常處理的方法為止,這一過(guò)程稱(chēng)為捕獲異常。假如在methodC()方法發(fā)生異常9.2.1異常的拋出與捕獲捕獲并處理異常最常用的方法是用try-catch-finally語(yǔ)句,一般格式為:try{//需要處理的代碼}catch(ExceptionType1exceptionObject){//異常處理代碼}[catch(ExceptionType2exceptionObject){//異常處理代碼}finally{//最后處理代碼}]9.2.2try-catch-finally語(yǔ)句try塊將程序中可能產(chǎn)生異常的代碼段用大括號(hào)括起來(lái),該塊內(nèi)可能拋出一種或多種異常。catch塊用來(lái)捕獲異常,括號(hào)中指明捕獲的異常類(lèi)型及異常引用名,類(lèi)似于方法的參數(shù),它指明了catch語(yǔ)句所處理的異常。大括號(hào)中是處理異常的代碼。catch語(yǔ)句可以有多個(gè),用來(lái)處理不同類(lèi)型的異常。finally塊是可選項(xiàng)。異常的產(chǎn)生往往會(huì)中斷應(yīng)用程序的執(zhí)行,而在異常產(chǎn)生前,可能有些資源未被釋放。有時(shí)無(wú)論程序是否發(fā)生異常,都要執(zhí)行一段代碼,這時(shí)就可以通過(guò)finally塊實(shí)現(xiàn)。無(wú)論異常產(chǎn)生與否finally塊都會(huì)被執(zhí)行。inta=5;try{intb=a/0;System.out.println("b="+b);}catch(ArithmeticExceptione){e.printStackTrace();}System.out.println("a="+a);//異常處理后程序繼續(xù)執(zhí)行程序9.2DivideDemo.java該行產(chǎn)生異常程序中調(diào)用了異常對(duì)象的printStackTrace()方法,它從控制臺(tái)輸出異常棧跟蹤。從棧跟蹤中我們可以了解到發(fā)生的異常類(lèi)型和發(fā)生異常的源代碼的行號(hào)。在異常類(lèi)的根類(lèi)Throwable中還定義了其他方法,如下所示:publicvoidprintStackTrace():在標(biāo)準(zhǔn)錯(cuò)誤輸出流上輸出異常調(diào)用棧的軌跡。publicStringgetMessage():返回異常對(duì)象的細(xì)節(jié)描述。publicvoidprintStackTrace(PrintWriters):在指定輸出流上輸出異常調(diào)用棧的軌跡。publicStringtoString():返回異常對(duì)象的簡(jiǎn)短描述,是Object類(lèi)中同名方法的覆蓋。異常類(lèi)的方法publicclassInputCharDemo{publicstaticvoidmain(String[]args){System.out.print("請(qǐng)輸入一個(gè)字符:");try{charc=(char)System.in.read();System.out.println("c="+c);}catch(IOExceptione){System.out.println(e);}}程序9.3InputCharDemo.javatry{if(value==0){System.out.println("無(wú)異常發(fā)生.");return;}elseif(value==1){inti=0;System.out.println(4/i);}elseif(value==2){intiArray[]=newint[4];iArray[4]=10;}程序9.4MultiExceptionDemo.java}catch(ArithmeticExceptione){System.out.println("捕獲到:"+e.toString());}catch(ArrayIndexOutOfBoundsExceptione){System.out.println("捕獲到:"+e.toString());}catch(Exceptione){System.out.println("Willnotbeexcecuted");}finally{System.out.println("執(zhí)行finally塊:"+value);}}publicstaticvoidmain(String[]args){method(0);method(1);method(2);}面向?qū)ο蟪绦蛟O(shè)計(jì)9.3捕獲多個(gè)異常如果在多個(gè)catch塊捕獲的異常使用相同的代碼處理,則可以?xún)H用一個(gè)catch塊處理,而不必單獨(dú)捕獲每個(gè)異常,這就減少了代碼重復(fù)。捕獲多個(gè)異常要在一個(gè)catch語(yǔ)句中處理多個(gè)異常,需要使用“或”運(yùn)算符(|)分隔多個(gè)異常。inta=88,b=0;intresult;char[]letter={'A','B','C'};for(inti=0;i<2;i++){try{if(i==0)result=a/b;elseletter[5]='X';}程序9.5MultiCatchDemo.javacatch(ArithmeticException|ArrayIndexOutOfBoundsExceptionme){System.out.println("捕獲到異常:"+me);}程序運(yùn)行當(dāng)嘗試除以0時(shí),將產(chǎn)生一個(gè)ArithmeticException錯(cuò)誤。當(dāng)嘗試越界訪問(wèn)letter數(shù)組時(shí),將產(chǎn)生一個(gè)ArrayIndexOutOfException錯(cuò)誤,兩個(gè)異常被同一個(gè)catch語(yǔ)句捕獲。注意,多重捕獲的每個(gè)形參隱含地為final,所以不能為其賦新值。面向?qū)ο蟪绦蛟O(shè)計(jì)9.4throws短語(yǔ)和throw語(yǔ)句所有的異常都產(chǎn)生在方法(包括構(gòu)造方法)內(nèi)部的語(yǔ)句。有時(shí)方法中產(chǎn)生的異常不需要在該方法中處理,可能需要由該方法的調(diào)用方法處理,這時(shí)可以在聲明方法時(shí)用throws子句聲明拋出異常,將異常傳遞給調(diào)用該方法的方法處理。聲明方法拋出異常的格式如下:throws短語(yǔ)returnTypemethodName([paramlist])throwsExceptionList{//方法體}聲明方法拋出異常到目前為止,處理的異常都是由程序產(chǎn)生的,并由程序自動(dòng)拋出,然而也可以創(chuàng)建一個(gè)異常對(duì)象,然后用throw語(yǔ)句拋出,或者將捕獲到的異常對(duì)象用throw語(yǔ)句再次拋出,throw語(yǔ)句的格式如下:throw語(yǔ)句

throwexceptInstance;exceptInstance可以是用戶(hù)創(chuàng)建的異常對(duì)象,也可以是程序捕獲到的異常對(duì)象,該實(shí)例必須是Throwable類(lèi)或其子類(lèi)的實(shí)例,請(qǐng)看下面例子。publicstaticvoidmethod()throwsIOException{try{

thrownewIOException("文件未找到");}catch(IOExceptione){ System.out.println("捕獲到異常");

throwe;}}程序9.7ThrowExceptionDemo.java拋出一個(gè)異常拋出捕獲的異常publicstaticvoidmain(String[]args){ try{ method(); }catch(IOExceptione){ System.out.println("再次捕獲:"+e); }}面向?qū)ο蟪绦蛟O(shè)計(jì)9.5try-with-resources語(yǔ)句Java程序中經(jīng)常需要?jiǎng)?chuàng)建一些對(duì)象(如I/O流、數(shù)據(jù)庫(kù)連接),這些對(duì)象在使用完后需要關(guān)閉。忘記關(guān)閉這些對(duì)象可能導(dǎo)致內(nèi)存泄露,并引起其他問(wèn)題。在JDK7之前,通常使用finally語(yǔ)句來(lái)確保一定會(huì)調(diào)用close()方法:概述try{//打開(kāi)資源}catch(Exceptione){//處理異常}finally{//關(guān)閉資源}如果在調(diào)用close()方法也可能拋出異常,那么也要處理這種異常。這樣編寫(xiě)的程序代碼會(huì)變得冗長(zhǎng)。例如,下面是打開(kāi)一個(gè)數(shù)據(jù)庫(kù)連接的典型代碼:Connectionconnection=null;try{//創(chuàng)建連接對(duì)象并執(zhí)行操作}catch(Exceptione){//處理異常}finally{if(connection!=null){try{connection.close();}catch(SQLExceptione){//處理異常}}}冗長(zhǎng)乏味的代碼JDK7提供的自動(dòng)關(guān)閉資源的功能為管理資源(如文件流、數(shù)據(jù)庫(kù)連接等)提供了一種更加簡(jiǎn)便的方式。這種功能是通過(guò)一種新的try語(yǔ)句實(shí)現(xiàn)的,叫try-with-resources,有時(shí)稱(chēng)為自動(dòng)資源管理。try-with-resources的主要好處是可以避免在資源(如文件流)不需要時(shí)忘記將其關(guān)閉。try-with-resources語(yǔ)句try-with-resources語(yǔ)句的基本形式如下:try(resource-specification){//使用資源}[catch(Exceptione){//處理異常}]try-with-resources語(yǔ)句控制離開(kāi)try塊后,創(chuàng)建的資源將自動(dòng)調(diào)用close()方法關(guān)閉,代碼簡(jiǎn)潔catch塊是可選的Java9增強(qiáng)了try-with-resources語(yǔ)句的功能,允許在try塊外部創(chuàng)建資源對(duì)象,然后在try-with-resources語(yǔ)句中使用這些對(duì)象。示例如下:try-with-resources語(yǔ)句并非所有的資源都可以自動(dòng)關(guān)閉。只有實(shí)現(xiàn)了java.lang.AutoCloseable接口的那些資源才可自動(dòng)關(guān)閉。該接口是Java7新增的,它定義了close()方法。java.io.Closeable接口繼承了AutoCloseable接口。這兩個(gè)接口被所有的I/O流類(lèi)實(shí)現(xiàn),包括FileInputStream和FileOutputStream。因此,在使用I/O流(包括文件流)時(shí),可以使用try-with-resources語(yǔ)句。publicvoidmethod(Connectionconn,ResultSetrs){try(conn;rs){while(rs.next()){//處理檢索的數(shù)據(jù)}}catch(SQLExceptionex){//執(zhí)行某種操作//異??赡苡刹徽_的SQL語(yǔ)句引起}}面向?qū)ο蟪绦蛟O(shè)計(jì)9.6自定義異常類(lèi)盡管Java已經(jīng)預(yù)定義了許多異常類(lèi),但有時(shí)還需要定義自己的異常。編寫(xiě)自定義異常類(lèi)實(shí)際上是繼承一個(gè)API標(biāo)準(zhǔn)異常類(lèi),用新定義的異常處理信息覆蓋原有信息的過(guò)程。常用的編寫(xiě)自定義異常類(lèi)的模式如下:自定義異常類(lèi)publicclassCustomExceptionextendsException{

publicCustomException(){}

publicCustomException(Stringmessage){

super(message);

}}packagecom.boda.xy;publicclassNegativeValueExceptionextendsException{publicNegativeValueException()

{}

publicNegativeValueException(Stringmessage){

super(message);

}}有了上述自定義異常,我們?cè)诔绦蛑芯涂梢允褂盟?。假設(shè)編寫(xiě)程序要求用戶(hù)輸入圓半徑,計(jì)算圓面積。該程序要求半徑值應(yīng)該為正值。程序代碼如下。程序9.9NegativeValueException.javavarinput=newScanner(System.in);varradius=0.0;vararea=0.0;System.out.print("請(qǐng)輸入半徑值:");try{radius=input.nextDouble();if(radius<0){thrownewNegativeValueException("半徑值不能小于0。");}else{area=Math.PI*radius*radius;System.out.println("圓的面積是:"+area);}}catch(NegativeValueExceptionnve){System.out.println(nve.getMessage());}程序9.10CustomExceptionDemo.java面向?qū)ο蟪绦蛟O(shè)計(jì)9.7案例:數(shù)組不匹配異常有一個(gè)名為com.boda.xy.ArrayUtils的實(shí)用工具類(lèi),該類(lèi)有一個(gè)名為addArray的靜態(tài)方法,用于對(duì)兩個(gè)長(zhǎng)度相同的數(shù)組相加。addArray的簽名如下:publicstaticlong[]addArray(int[]

array1,int[]array2)throwsMismatchedArrayException,NullPointerException

問(wèn)題描述如果兩個(gè)參數(shù)的長(zhǎng)度不相同(比如,一個(gè)長(zhǎng)度是3,一個(gè)長(zhǎng)度是5),方法拋出一個(gè)自定義異常MismatchedArrayException,要求該異常類(lèi)的toString方法必須返回下面這個(gè)值:

數(shù)組大小不同。第一個(gè)數(shù)組大小是3,第二個(gè)數(shù)組大小是5.如果其中一個(gè)數(shù)組為null,該方法將拋出NullPointerException異常。編程測(cè)試產(chǎn)生這兩種異常的情形。(1)由于MismatchedArrayException異常只在addArray靜態(tài)方法中使用,所以這里可將該類(lèi)定義為外層類(lèi)ArrayUtils類(lèi)的靜態(tài)內(nèi)部類(lèi)。(2)為MismatchedArrayException類(lèi)定義一個(gè)帶兩個(gè)參數(shù)的構(gòu)造方法,因?yàn)閽伋鲈摦惓?duì)象時(shí)要傳遞兩個(gè)數(shù)組的大小。(3)覆蓋MismatchedArrayException類(lèi)的toString()方法輸出異常信息。(4)在addArray()方法中,當(dāng)兩個(gè)數(shù)組大小不相等時(shí),使用throw語(yǔ)句拋出創(chuàng)建的MismatchedArrayException對(duì)象。設(shè)計(jì)思路publicstaticclassMismatchedArrayExceptionextendsException{intx=0,y=0;publicMismatchedArrayException(intx,inty){this.x=x;this.y=y;}@OverridepublicStringtoString(){ return"數(shù)組大小不同。第一個(gè)數(shù)組大小是"+x+",第二個(gè)數(shù)組大小是"+y+"."; }}程序10.12ArrayUtils.javapublicstaticlong[]addArray(int[]array1,int[]array2) throwsMismatched

溫馨提示

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

評(píng)論

0/150

提交評(píng)論