第5章 異常處理
5-1?程序中的錯(cuò)誤有哪幾種?分別能夠在什么時(shí)刻被發(fā)現(xiàn)?
【答】?程序錯(cuò)誤按照性質(zhì)可分為3類(lèi):語(yǔ)法錯(cuò)、語(yǔ)義錯(cuò)、邏輯錯(cuò)。
1?語(yǔ)法錯(cuò):違反語(yǔ)法規(guī)范的錯(cuò)誤成為語(yǔ)法錯(cuò)( syntax error ),這類(lèi)錯(cuò)誤通常在編譯時(shí)發(fā)現(xiàn),又稱(chēng)為編譯錯(cuò),如標(biāo)識(shí)符未聲明、表達(dá)式中運(yùn)算符與操作數(shù)類(lèi)型不兼容、變量賦值時(shí)的類(lèi)型與聲明時(shí)的類(lèi)型不匹配、括號(hào)不匹配、語(yǔ)句末缺少分號(hào)等。
2?語(yǔ)義錯(cuò):如果在程序的語(yǔ)法上正確,但在語(yǔ)義上存在錯(cuò)誤,則稱(chēng)為語(yǔ)義錯(cuò)(?semantic error),又稱(chēng)為運(yùn)行錯(cuò)(run-time error),語(yǔ)義錯(cuò)不能被編譯系統(tǒng)發(fā)現(xiàn),只有到程序運(yùn)行時(shí)才能被發(fā)現(xiàn),如輸入數(shù)據(jù)格式錯(cuò)、除數(shù)為0錯(cuò)、給變量賦予超出其范圍的值錯(cuò)等。
3?邏輯錯(cuò):如果程序通過(guò)編譯,可運(yùn)行,但運(yùn)行結(jié)果與期望值不符,則這類(lèi)錯(cuò)誤稱(chēng)為邏輯錯(cuò)(logic error),例如,由于循環(huán)條件不正確而沒(méi)有結(jié)果,循環(huán)次數(shù)不對(duì)等因素導(dǎo)致計(jì)算結(jié)果不正確等。
?
5-2? Java為什么要采用異常處理機(jī)制?Java的異常處理是怎樣實(shí)現(xiàn)的?異常處理機(jī)制能夠解決程序中遇到的所有錯(cuò)誤嗎?哪些錯(cuò)誤不是異常處理能夠解決的?
【答】?異常處理和捕獲和處理運(yùn)行時(shí)錯(cuò)誤的一種機(jī)制。異常處理機(jī)制使程序具有處理錯(cuò)誤的能力。即使發(fā)生了運(yùn)行錯(cuò),應(yīng)用程序能夠捕獲異常并及時(shí)處理異常,使程序從運(yùn)行錯(cuò)誤中很好地恢復(fù)并繼續(xù)運(yùn)行,而不會(huì)導(dǎo)致程序運(yùn)行非正常終止。而且如果當(dāng)前方法沒(méi)有能力處理異常,還可以將異常轉(zhuǎn)交給調(diào)用者處理。異常處理機(jī)制將運(yùn)行時(shí)錯(cuò)誤封裝成若干錯(cuò)誤類(lèi)和異常類(lèi),并提供異常處理語(yǔ)句用于處理在程序中實(shí)現(xiàn)對(duì)運(yùn)行時(shí)錯(cuò)誤的發(fā)現(xiàn)和及時(shí)處理。異常處理機(jī)制并不能解決程序中的所有錯(cuò)誤,例如內(nèi)存溢出、棧溢出等。
?
5-3??請(qǐng)說(shuō)出5個(gè)Java的異常類(lèi)。
【答】?算術(shù)異常ArithmeticException、空對(duì)象異常NullPointerException、類(lèi)型強(qiáng)制轉(zhuǎn)換異常ClassCastException、負(fù)數(shù)組長(zhǎng)度異常NegativeArraySizeException、數(shù)組下標(biāo)越界異常ArrayIndexOutOfBundsException等
?
5-4??請(qǐng)問(wèn)運(yùn)行沒(méi)有main()方法的類(lèi)會(huì)怎樣?
【答】?此類(lèi)錯(cuò)誤是Error類(lèi),當(dāng)運(yùn)行沒(méi)有main()方法的類(lèi)時(shí),則產(chǎn)生類(lèi)定義未找到的錯(cuò)誤(NoClassDefFoundError)。
?
5-5??舉例說(shuō)明你在調(diào)試程序時(shí),遇到過(guò)哪些錯(cuò)誤和異常,采取什么辦法解決問(wèn)題的。
【答】1.無(wú)效的游標(biāo)狀態(tài)
修改:首先查看ResultSet是否為空,若為空則修改之;其次,也是我遇到的,就是:舉個(gè)例子說(shuō)明,如下
rs.getString(1);
rs.getString(3);//注意3和2的順序顛倒了
rs.getString(2);//此時(shí)會(huì)出現(xiàn)異常
說(shuō)明:ResultSet只能按順序訪(fǎng)問(wèn)列的值,不能顛倒,我猜想這可能是JDBC的一個(gè)BUG吧。不過(guò)后來(lái)我看.NET中的DataReader類(lèi)后才恍然大悟,原來(lái),ResultSet的游標(biāo)每向后移動(dòng),前面的數(shù)據(jù)就會(huì)被丟棄掉,這樣做有利于提高訪(fǎng)問(wèn)速度。
2. ResultSet is closed
原因:一個(gè)Statement只能維持一個(gè)ResultSet為打開(kāi)狀態(tài),后面的覆蓋前面的,舉個(gè)例子:
ResultSet rs1 = stmt.excuteQuery();
ResultSet rs2 = stmt.excuteQuery();
String s = rs1.getString(1);//出現(xiàn)異常,因?yàn)?/span>rs1已經(jīng)被關(guān)閉
3.?連接占線(xiàn)導(dǎo)致另一個(gè)?hstmt
原因:一個(gè)Connection只能維持一個(gè)Statement為打開(kāi)狀態(tài)
???一個(gè)例子:
Statement stmt1 = con.createStatement();
Statement stmt2 = con.createStatement();
stmts.excuteQuery(sql);//出現(xiàn)異常
其他異常
空指針異常
空指針異常應(yīng)該說(shuō)是最常見(jiàn)的異常了
原因主要有以下幾點(diǎn):
1.未初始化的變量(雖然已經(jīng)聲明)
2.使用了未初始化的對(duì)象(雖然已經(jīng)聲明)
注:引起這個(gè)異常的根本原因有可能隱藏的很深,空指針異常只不過(guò)是個(gè)表象而已(又被不幸的我遇到了).
?
5-6??如何處理除數(shù)為0異常?
【答】?進(jìn)行除數(shù)運(yùn)算時(shí),先判斷除數(shù)是否為0,若為0,則跳出提示。
?
5-7??怎樣處理數(shù)組下標(biāo)異常?
【答】?使用數(shù)組前先,判斷下標(biāo)是否小于數(shù)值長(zhǎng)度,若不小于則提示數(shù)組下標(biāo)有誤。
?
5-8??說(shuō)明采用什么語(yǔ)句能夠捕獲并處理異常?
【答】?Java提供try-catch-finally語(yǔ)句來(lái)捕獲和處理一個(gè)或多個(gè)異常。其中,try、catch、finally是關(guān)鍵字。catch字句可以有一個(gè)或多個(gè),但至少要有一個(gè)catch字句,finally字句可以省略。
?
5-9??為什么將字符串轉(zhuǎn)換成數(shù)值類(lèi)型時(shí)會(huì)拋出異常?拋出什么異常?
【答】?并不是所有的字符串都能轉(zhuǎn)換成數(shù)值型,當(dāng)遇到一個(gè)不能轉(zhuǎn)轉(zhuǎn)換成數(shù)值型的字符串時(shí),Java拋出NumberFormatException異常。
?
5-10?說(shuō)明throw語(yǔ)句與throws子句的區(qū)別。
【答】1.throws?用于拋出方法層次的異常,?并且直接由些方法調(diào)用異常處理類(lèi)來(lái)處理該異常,所以它常用在方法的后面。比如?public static void main(String[] args) throws SQLException
2.throw?用于拋出代碼層次的異常,常用于方法塊里面的代碼,常和try...catch ....語(yǔ)句塊搭配實(shí)用,比throws的層次要低。
?
5-11?什么情況下需要自定義異常類(lèi)?
【答】?當(dāng)Java提供的異常類(lèi)不能滿(mǎn)足需要時(shí),程序需要對(duì)自己拋出的異常類(lèi)進(jìn)行特殊處理,則可以自定義異常類(lèi)。