java程序錯誤類型及異常處理1_第1頁
java程序錯誤類型及異常處理1_第2頁
java程序錯誤類型及異常處理1_第3頁
java程序錯誤類型及異常處理1_第4頁
java程序錯誤類型及異常處理1_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

/java程序錯誤類型與異常處理一、程序的錯誤類型在程序設(shè)計中,無論規(guī)模是大是小,錯誤總是難免的。程序的設(shè)計很少有能夠一次完成,沒有錯誤的(不是指HelloWorld這樣的程序,而是要實現(xiàn)一定的功能,具備一定實用價值的程序),在編程的過程中由于種種原因,總會出現(xiàn)這樣或那樣的錯誤,這些程序的錯誤就是我們常說的“Bug”,而檢測并修正這些錯誤的方法就是“Debug”(調(diào)試)。

基本上所有的集成開發(fā)環(huán)境都提供了強大的和程序調(diào)試功能,在程序進行編譯,連接,運行時,會對程序中錯誤進行診斷。程序的錯誤可以抽象分為三類:語法錯誤、運行錯誤和邏輯錯誤。

1、語法錯誤是指由于編程中輸入不符合語法規(guī)則而產(chǎn)生的。程序編譯就通不過,程序不能運行起來。此類錯誤最簡單,調(diào)試起來比較容易例如:表達式不完整、缺少必要的標(biāo)點符號、關(guān)鍵字輸入錯誤、數(shù)據(jù)類型不匹配、循環(huán)語句或選擇語句的關(guān)鍵字不匹配等。通常,編譯器對程序進行編譯的過程中,會把檢測到的語法錯誤以提示的方式列舉出來,又稱為編譯錯誤。

語法錯誤的調(diào)試,則可以由集成開發(fā)環(huán)境提供的調(diào)試功能來實現(xiàn),在程序進行編譯時,編譯器會對程序中的語法錯誤進行診斷。編譯診斷的語法錯誤分為3中:致命錯誤、錯誤和警告。

(1)致命錯誤:這個錯誤大多是編譯程序內(nèi)部發(fā)生的錯誤,發(fā)生這類錯誤時,編譯被迫中止,只能重新啟動編譯程序,但是這類錯誤很少發(fā)生,為了安全,編譯前最好還是先保存程序。

(2)錯誤:這個錯誤通常是在編譯時,語法不當(dāng)所引起的。例如:括號不匹配,變量未聲明等。產(chǎn)生這類錯誤時,編譯程序會出現(xiàn)報錯提示,我們根據(jù)提示對源程序進行修改即可。這類錯誤是出現(xiàn)最多的。

(3)警告:是指被編譯程序懷疑有錯,但是不確定,有時可強行通過。例如:沒有加void聲明的主函數(shù)沒有返回值,double數(shù)據(jù)被轉(zhuǎn)換為float類型等。這些警告中有些會導(dǎo)致錯誤,有些可以通過。常規(guī)解決方法:此類錯誤一般程序編譯系統(tǒng)會自動提示相應(yīng)的錯誤地點和錯誤原因,比如哪一行代碼少了個括號等諸如此類的提示,常見的錯誤,看懂直接改正即可,如果是看不懂原因,可以將錯誤提示信息輸入搜索引擎查找一下,一般都能找到具體的解決辦法。或者有些編程平臺會本身提供一個本地或者在線的信息庫,提供詳細的錯誤原因和解決辦法,比如微軟的.NET開發(fā)平臺。

2、運行錯誤指程序在運行過程中出現(xiàn)的錯誤。程序通過語法錯誤檢測,但是運行的時候出現(xiàn)錯誤,導(dǎo)致程序被迫終止,此類錯誤有特定的發(fā)生條件,因此能夠準(zhǔn)確的定位錯誤代碼段,因而調(diào)試也比較方便。例如:除法運算時除數(shù)為0

、數(shù)組下標(biāo)越界、文件打不開、磁盤空間不夠、數(shù)據(jù)庫連接錯誤等。此類錯誤發(fā)生時,編譯平臺一般也會提示相應(yīng)的信息,對于常規(guī)的錯誤會有比較精確地提示,但有時提示的錯誤原因會比較模糊,但因為此類錯誤一般在程序運行時,只在特定的條件下才會發(fā)生,所以根據(jù)錯誤發(fā)生的條件,能夠大致判斷程序出錯的代碼段,結(jié)合錯誤的原因,也能比較方便的調(diào)試出錯誤。

3、邏輯錯誤程序運行后,沒有得到設(shè)計者預(yù)期的結(jié)果,這就說明程序存在邏輯錯誤。這種錯誤在語法上是有效的,但是在邏輯上是錯誤的。程序運行了,也沒有出錯,但是執(zhí)行出來的結(jié)果不是用戶想要的,分為兩種情況:A、

能夠看出錯誤:比如查詢工資大于5000的人員名單,卻出現(xiàn)了3000的;B、

看不出錯誤,直到因緣際會發(fā)現(xiàn)程序肯定出錯了,后果很嚴(yán)重:比如進行一個符合大型運算,把某個常數(shù)輸入錯了,最后的結(jié)果人工無法判斷對錯,又以該結(jié)果進行其它的運算等等,最后發(fā)現(xiàn)錯了誤差過大,就得從頭排查錯誤。例如:使用了不正確的變量,指令的次序錯誤,循環(huán)的條件不正確,程序設(shè)計的算法考慮不周全等。通常,邏輯錯誤也會附帶產(chǎn)生運行錯誤。在一般情況下,編譯器在編譯程序時,不能檢測到程序中的邏輯錯誤,也不會產(chǎn)生邏輯錯誤的提示,因此邏輯錯誤比較難排除,需要程序員仔細的分析程序,并借助集成開發(fā)環(huán)境提供的調(diào)試工具,才能找到出錯的原因,并排除錯誤。

二、java的異常處理(錯誤處理)

程序的錯誤就是通常的異常,也叫Exception。

對于語法錯誤,java編譯系統(tǒng)在編就能發(fā)現(xiàn)檢查出錯誤。

對于邏輯錯誤,編譯系統(tǒng)是無法發(fā)現(xiàn)錯誤的,錯誤需要人為去發(fā)現(xiàn)排除錯誤。對于運行錯誤,Java語言中代表異常時,使用一個專門的類來代表一種特定的異常情況,在系統(tǒng)中傳遞的異常情況就是該類的對象,所有代表異常的類組成的體系就是Java語言中的異常類體系。

1、java異常類Java的異常是一個對象,所有的異常都直接或間接地繼承Throwable類。Throwable類的繼承層次結(jié)構(gòu)如下:

為了方便對于這些可傳遞對象的管理,JavaAPI中專門設(shè)計了java.lang.Throwable類,只有該類子類的對象才可以在系統(tǒng)的異常傳遞體系中進行。該類的兩個子類分別是:

1)Error類

該類代表錯誤,指程序無法恢復(fù)的異常情況。對于所有錯誤類型以與其子類,都不要求程序進行處理。常見的Error類例如內(nèi)存溢出StackOverflowError等。

2)Exception類

該類代表異常,指程序有可能恢復(fù)的異常情況。該類就是整個Java語言異常類體系中的父類。使用該類,可以代表所有異常的情況。

在JavaAPI中,聲明了幾百個Exception的子類分別來代表各種各樣的常見異常情況,這些類根據(jù)需要代表的情況位于不同的包中,這些類的類名均以Exception作為類名的后綴。如果遇到的異常情況,JavaAPI中沒有對應(yīng)的異常類進行代表,也可以聲明新的異常類來代表特定的情況。在這些異常類中,根據(jù)是否是程序自身導(dǎo)致的異常,將所有的異常類分為兩種:

a)

RuntimeException與其所有子類

該類異常屬于程序運行時異常,也就是由于程序自身的問題導(dǎo)致產(chǎn)生的異常,例如數(shù)組下標(biāo)越界異常ArrayIndexOutOfBoundsException等。

該類異常在語法上不強制程序員必須處理,即使不處理這樣的異常也不會出現(xiàn)語法錯誤。

b)

其它Exception子類

該類異常屬于程序外部的問題引起的異常,也就是由于程序運行時某些外部問題導(dǎo)致產(chǎn)生的異常,例如文件不存在異常等。

該類異常在語法上強制程序員必須進行處理,如果不進行處理則會出現(xiàn)語法錯誤。

熟悉異常類的分類,將有助于后續(xù)語法中的處理,也使得在使用異常類時可以選擇恰當(dāng)?shù)漠惓n愵愋汀?/p>

2、常見的error類

異常類名用途LinkageError動態(tài)鏈接失敗VirtualMachineError虛擬機錯誤AWTErrorAWT錯誤

3、常見運行時異常類異常類名用途ArithmeticException數(shù)學(xué)運算異常,比如除數(shù)為零的異常IndexOutOfBoundsException下標(biāo)越界異常,比如集合、數(shù)組等ArrayIndexOutOfBoundsException訪問數(shù)組元素的下標(biāo)越界異常StringIndexOutOfBoundsException字符串下標(biāo)越界異常ClassCaseException類強制轉(zhuǎn)換異常NullpointerException當(dāng)程序試圖訪問一個空數(shù)組中的元素,或訪問一個空對象中的方法或變量時產(chǎn)生的異常。

4、常用的非運行時異常異常類名用途ClassNotFoundException指定類或接口不存在的異常IllegalAccessException非法訪問異常Ioexception輸入輸出異常找不到指定文件的異常ProtocolException網(wǎng)絡(luò)協(xié)議異常SocketExceptionSocket操作異常MalformedURLException統(tǒng)一資源定位符(URL)的格式不正確的異常

5、Java的異常處理機制描述如下:在一個方法的運行過程中,如果發(fā)生了異常,則這個方法(或者是Java虛擬機)生成一個代表該異常的對象(它包含了異常的詳細信息),并把它交給運行時系統(tǒng),運行時系統(tǒng)尋找相應(yīng)的代碼來處理這一異常。我們把生成異常對象并把它提交給運行時系統(tǒng)的過程稱為拋出(throw)一個異常。運行時系統(tǒng)尋找相應(yīng)的代碼來處理這一異常,系統(tǒng)在方法的調(diào)用棧中查找,從產(chǎn)生異常的方法開始進行回朔,沿著被調(diào)用的順序往前尋找,直到找到包含相應(yīng)異常處理的方法為止。其過程如圖10-1所示。這一過程稱為捕獲(catch)一個異常。如該異常未進行成功捕獲,則程序?qū)⒔K止運行。

5、異常捕獲和處理

格式:try{正常程序段,可能拋出異常;}catch(異常類1

異常變量){捕捉異常類1有關(guān)的處理程序段;}catch(異常類2

異常變量){捕捉異常類2有關(guān)的處理程序段;}……finally{一定會運行的程序代碼;}

l

try塊——捕獲異常:用于監(jiān)控可能發(fā)生異常的程序代碼塊是否發(fā)生異常,如果發(fā)生異常,Try代碼塊將拋出異常類所產(chǎn)生的對象并立刻結(jié)束執(zhí)行,而轉(zhuǎn)向異常處理catch部分。對于系統(tǒng)產(chǎn)生的異?;虺绦驂K中未用try監(jiān)控所產(chǎn)生的一場,將一律由java編譯系統(tǒng)自動將異常對象拋出。l

catch塊——處理異常:拋出的異常對象如果屬于catch內(nèi)所定義的異常類,則catch會捕獲該異常,并進入catch中的對應(yīng)代碼段繼續(xù)運行程序,如果異常對象不屬于catch中所定義的異常類,則進入finally塊繼續(xù)運行程序。Catch包括兩個參數(shù):一個是類名,指出捕獲的異常類型,必須使Throwable類的子類;一個是參數(shù)名,用來引用被捕獲的對象。Catch塊所捕獲的對象并不需要與它的參數(shù)類型精確匹配,它可以捕獲參數(shù)中指出的異常類的對象與其所有子類的對象l

finally塊——最終處理:無論是否發(fā)生異常都會執(zhí)行的語句塊。比如執(zhí)行關(guān)閉打開的文件、刪除臨時文件,關(guān)閉數(shù)據(jù)庫連接等操作。

注意:l

一個try、catch、finally塊之間不能插入任何其它代碼l

catch可以有多個,try和finally只能有一個l

try后面必須要跟catch、finally其中的一個,即但一個try、catch、finally語句只能省略catch、finally中的一個。

定義多個catch可精確地定位java異常。如果為子類的異常定義了特殊的catch塊,而父類的異常則放在另外一個catch塊中,此時,必須滿足以下規(guī)則:子類異常的處理塊必須在父類異常處理塊的前面,否則會發(fā)生編譯錯誤。所以,越特殊的異常越在前面處理,越普遍的異常越在后面處理。這類似于制訂防火墻的規(guī)則次序:較特殊的規(guī)則在前,較普通的規(guī)則在后。

異常類常用方法常用非法用途VoidStringgetMessage()返回異常對象的一個簡短描述VoidStringtoString()獲取異常對象的詳細信息VoidprintStackTrace()在控制臺上打印異常對象和它的追蹤信息

6、異常實例1)

數(shù)學(xué)運算異常classMathException{

publicstaticvoidmain(String

args[]){

inta=5,b=0;

intc=a/b;

//除數(shù)為0,出現(xiàn)異常

System.out.print(c);

}}

在命令提示符下運行該程序,可以發(fā)現(xiàn)編譯正常,但是執(zhí)行時出現(xiàn)錯誤的提示如下:Exceptioninthread"main"java.lang.ArithmeticException:/byzero

atMathException.main(MathException.java:4)

翻譯過來就是:在類java.lang.ArithmeticException主線程中“main”方法中出現(xiàn)異常:除數(shù)為零,(MathException.java:4“此處指MathException類中的第四行”)

這是一個典型的運行錯誤,程序告訴了一下幾個信息;l

出錯的異常類:java.lang.ArithmeticExceptionl

出錯的類:MathExceptionl

出錯的代碼:MathException.java:4

因為編譯系統(tǒng)給出了出錯的原因和出錯類的位置,可以方便地進行代碼調(diào)試。

2)捕獲數(shù)學(xué)運算異常的處理

publicclassTryCatchDemo{publicstaticvoidmain(Stringargs[]){try{inta=8,b=0;intc=a/b;System.out.print(c);}//ArithmeticException是異常類的名稱,e是引用的參數(shù)名稱catch(ArithmeticExceptione){System.out.println("發(fā)生的異常簡短描述是:"+e.getMessage());System.out.println("發(fā)生的異常詳細信息是:"+e.toString());}}}

程序執(zhí)行結(jié)果:發(fā)生的異常簡短描述是:/byzero發(fā)生的異常詳細信息是:java.lang.ArithmeticException:/byzero

3)數(shù)組下標(biāo)越界異常

publicclassarrayException{publicstaticvoidmain(String[]args){//被監(jiān)視的代碼塊try{int[]a=newint[4];a[4]=9;}//處理下標(biāo)越界異常catch(ArrayIndexOutOfBoundsExceptionaiobe){System.out.println("這里出現(xiàn)的錯誤類型是:數(shù)組下標(biāo)越界??!");}//處理空引用異常catch(NullPointerExceptionnpe){System.out.println("這里出現(xiàn)的錯誤類型是:空引用??!");}finally{System.out.println("程序無條件執(zhí)行該語句!");}}}

三、異常的拋出

異常的拋出可以分為兩大類:l

系統(tǒng)自動拋出異常比如上面的例子就是系統(tǒng)自動拋出異常,通過trycatch捕獲異常對象,并繼續(xù)相應(yīng)的處理。

l

通過關(guān)鍵字throw將異常對象顯性地拋出。即在程序中生成自己的異常對象,即異常可以不是出錯產(chǎn)生,而是人為編寫代碼主動拋出。顯性拋出異常從某種程度上實現(xiàn)了將處理異常的代碼從正常流程代碼中分離開了,使得程序的主線保證相對完整,同時增加了程序的可讀性和可維護性。異常沿著調(diào)用層次向上拋出,交由調(diào)用它的方法來處理。

為什么要在方法中拋出異常?系統(tǒng)自動拋出異常一般就能解決大部分問題,但有時候,程序會產(chǎn)生特定的要求,需要由用戶自己定義異常信息,又或者聯(lián)合開發(fā)程序模塊時,不同程序員需要將各自負責(zé)代碼部分盡量避免因程序出錯影響其他人的編碼,都需要顯式拋出異常,以便程序進行處理。這時候就需要在方法中拋出異常。

異常拋出的語法:

throw

new

異常類();其中異常類必須Throwable類與其子類。比如:thrownewThrowableObject();

ArithmeticException

e=newArithmeticException();

throwe;

throws子句的方法聲明的一般格式如下:<類型說明>方法名(參數(shù)列表)

throws

<異常類型列表>{

方法體;}

舉例:

classThrowException{//throwOne方法后用throws聲明異常類ArithmeticExceptionstaticvoidthrowOne(inti)throwsArithmeticException{if(i==0)thrownewArithmeticException("i值為零");//用throw拋出一個異常}publicstaticvoidmain(Stringargs[]){//捕獲異常try{throwOne(0);}catch(ArithmeticExceptione){System.out.println("已捕獲到異常錯誤:"+e.getMessage());}}}

程序執(zhí)行結(jié)果:已捕獲到異常錯誤:i值為零

例:

importjava.io.*;classFather{//父類方法,沒有拋出異常publicvoidmyFunction(){System.out.println("這里是父類方法,該方法沒有異常拋出??!");}}classSonextendsFather{//子類重寫父類方法,有捕獲異常拋出publicvoidmyFunction()throwsInterruptedException{System.out.println("這里是子類方法,該方法拋出InterruptedException異常??!");}}publicclassTestExceptionDemo{publicstaticvoidmain(String[]args){//創(chuàng)建子類對象Sons=newSon();//受監(jiān)視的代碼try{s.myFunction();}//異常處理代碼catch(InterruptedExceptione){e.printStackTrace();}}}

例:重新拋出異常對象程序執(zhí)行時,要求用戶從鍵盤輸入一個字符號。當(dāng)輸入‘0’時,程序執(zhí)行結(jié)果:devidedby0;當(dāng)輸入非‘0’字符時,程序執(zhí)行運算出的結(jié)果。importjava.io.*;classJavaThrows{

publicint

compute(intx)throws

ArithmeticException

{

intz=10/x;

//可能拋出異常類型ArithmeticException的對象

returnz;

}

publicvoidmethod1()

{

intx;

try{

x=System.in.read();

//可能拋出異常類型IOException的對象;

x=x-48;

x=compute(x);

//拋出異常類型ArithmeticException的對象

System.out.println(x);

}

catch(IOExceptionioe){

//捕獲異常類型IOException的對象;

System.out.println("readerror");

}

catch(ArithmeticExceptione){

//捕獲異常類型ArithmeticException的對象

System.out.println("devidedby0");

}

}publicstaticvoidmain(Stringargs[]){

JavaThrowst1=newJavaThrows();

t1.method1();

}}四、自定義異常用戶自定義的異常類,只需繼承一個已有的異常類就可以了,包括繼承Execption類與其子類,或者繼承已自定義好的異常類。如果沒有特別說明,可以直接用Execption類作為父類。

自定義類的格式如下:class

異常類名extends

Exception{

……}

n

自定義異常類必須繼承自Throwable或Exception類,建議用Exception類。一般不把自定義異常作為Error的子類,因為Error通常被用來表示系統(tǒng)內(nèi)部的嚴(yán)重故障。n

當(dāng)自定義異常是從RuntimeException與其子類繼承而來時,該自定義異常是運行時異常,程序中可以不捕獲和處理它。n

當(dāng)自定義異常是從Throwable、Exception與其子類繼承而來時,該自定義異常是編譯時異常,也即程序中必須捕獲并處理它。

使用自定義異常的步驟如下:l

首先通過繼承java.lang.Exception類聲明自定義的異常類。l

在方法的聲明部分用throws語句聲明該方法可能拋出的異常。l

在方法體的適當(dāng)位置創(chuàng)建自定義異常類的對象,并用throw語句將異常拋出。l

調(diào)用該方法時對可能產(chǎn)生的異常進行捕獲,并處理異常。

例:自定義一個異常類,輸入一個數(shù),大于10,捕獲異常。

//MyExceptionDemo.javaclassMyExceptionextendsException{//繼承了Exception這個父類privateintdetail;MyException(inta){detail=a;}publicStringtoString(){return"MyException["+detail+"]";}}classMyExceptionDemo{staticvoidcompute(inta)throwsMyException{System.out.println("調(diào)用compute("+a+")");if(a>10){//a大于10,則拋出異常thrownewMyException(a);}System.out.println("常規(guī)退出");}publicstaticvoidmain(Stringargs[]){try{compute(1);//a小于10,常規(guī)退出compute(20);//a大于10,則拋出異常}catch(MyExceptione){System.out.println("捕捉"+e);//這樣就可以用自己定義的類來捕捉異常了}}}例:計算兩個數(shù)之和,當(dāng)任意一個數(shù)超出范圍(10,20)時,拋出自己的異常。

//NewException.javaclassNumberRangeExceptionextendsException{publicNumberRangeException(Stringmsg){super(msg);}//throws重新拋出異常NumberRangeExceptionpublicintCalcAnswer(Stringstr1,Stringstr2)throwsNumberRangeException{intint1,int2;intanswer=-1;try{int1=Integer.parseInt(str1);//可能產(chǎn)生異常對象NumberFormatExceptioneint2=Integer.parseInt(str2);//可能產(chǎn)生異常對象NumberFormatExceptioneif((int1<10)||(int1>20)||(int2<10)||(int2>20)){NumberRangeExc

溫馨提示

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

最新文檔

評論

0/150

提交評論