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