版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p><b> 目 錄</b></p><p><b> 一 引言1</b></p><p> 二 關(guān)于JDK和Java異常2</p><p> ?。ㄒ唬㎎ava異常定義2</p><p> ?。ǘ㎎ava中的異常類(lèi)2</p><p>
2、?。ㄈ㎎ava語(yǔ)言規(guī)范對(duì)異常處理的要求4</p><p> 三 Java異常的處理機(jī)制4</p><p> ?。ㄒ唬㎎ava異常處理機(jī)制具體實(shí)現(xiàn)4</p><p> (二)Java中異常發(fā)生的原因6</p><p> ?。ㄈ㎎ava異常處理的優(yōu)點(diǎn)6</p><p> 四 Java異常處理技術(shù)及其
3、應(yīng)用8</p><p><b> (一)拋出異常8</b></p><p><b> ?。ǘ┎东@異常8</b></p><p><b> ?。ㄈ┒褩?</b></p><p> ?。ㄋ模┳远x異常11</p><p> (五)關(guān)于圖形
4、界面程序的異常捕獲12</p><p> 五 Java異常處理基本原則14</p><p> (一)不要忽略已檢查型異常14</p><p> (二)不要一次捕獲所有的異常15</p><p> (三)使用finally塊釋放資源16</p><p> (四)異常不能影響對(duì)象的狀態(tài)17</
5、p><p> (五)注意丟失(或忽略)的異常17</p><p> (六)不要同時(shí)使用異常機(jī)制和返回值來(lái)處理異常20</p><p> (七)不要讓try塊過(guò)于龐大21</p><p><b> 六 結(jié)束語(yǔ)21</b></p><p><b> 致謝21</b&g
6、t;</p><p><b> 參考文獻(xiàn)22</b></p><p><b> 附錄、源代碼22</b></p><p> 基于Java的異常處理技術(shù)及其應(yīng)用</p><p> 摘 要 本文以Java軟件開(kāi)發(fā)工具箱JDK1.5.0作為環(huán)境,通過(guò)與一些編程語(yǔ)言的錯(cuò)誤處理相比較,介紹了J
7、ava中異常處理技術(shù)的由來(lái)、定義、規(guī)范和Java內(nèi)建的異常類(lèi),討論了Java中異常產(chǎn)生的原因、實(shí)現(xiàn),還對(duì)Java異常處理機(jī)制的優(yōu)點(diǎn)進(jìn)行了簡(jiǎn)述,就Java異常處理技術(shù)從拋出異常、捕獲異常、堆棧幀、自定義異常、圖形界面程序異常捕獲五個(gè)方面進(jìn)行了討論。本文還就Java異常處理技術(shù)的應(yīng)用做了一些探討,試圖從軟件開(kāi)發(fā)者的角度說(shuō)明Java異常處理技術(shù)在開(kāi)發(fā)中一些有價(jià)值的應(yīng)用。</p><p> 關(guān)鍵詞 Java語(yǔ)言 J
8、ava異常處理 JVM </p><p><b> 一 引言</b></p><p> 在程序設(shè)計(jì)中,盡管編寫(xiě)檢查和處理錯(cuò)誤的程序代碼很乏味,并且它們使程序源代碼顯得冗長(zhǎng),但是,錯(cuò)誤檢測(cè)和處理仍是任何健壯應(yīng)用程序最重要的組成部分之一。傳統(tǒng)的異常處理多采用返回值來(lái)標(biāo)識(shí)程序中出現(xiàn)的異常情況,這是程序員熟悉的一種方式,但卻有很多缺點(diǎn)。首先,一個(gè)API(Appli
9、cation Programming Interface 應(yīng)用編程接口)可以返回任意的返回值,而這些返回值本身并不能解釋是否代表一個(gè)異常情況發(fā)生或者發(fā)生異常的具體情況,需要調(diào)用API的程序自己判斷并解釋返回值的含義。其次,它并沒(méi)有一種機(jī)制來(lái)保證異常情況一定會(huì)得到處理,調(diào)用程序可以簡(jiǎn)單地忽略該返回值,從而需要調(diào)用API的程序員記住去檢測(cè)返回值并處理異常情況。這種方式還讓程序代碼變得晦澀冗長(zhǎng), 當(dāng)進(jìn)行容易出現(xiàn)異常情況的處理時(shí),比如:I/O操
10、作,程序中會(huì)出現(xiàn)很大的部分用于處理異常情況的switch分支,程序代碼的可讀性變得很差。</p><p> 相對(duì)于傳統(tǒng)異常處理方式的缺點(diǎn),Java異常處理機(jī)制提供了很好的解決方案。Java異常處理使開(kāi)發(fā)人員不用編寫(xiě)特殊代碼檢測(cè)返回值就能夠很容易地檢測(cè)錯(cuò)誤,并且把異常處理代碼和異常產(chǎn)生代碼明確地分開(kāi),通過(guò)拋出Java預(yù)定義或者自定義的異常,能夠表明程序中出現(xiàn)了什么樣的異常情況[1];而且Java的語(yǔ)言機(jī)制保證了異
11、常一定會(huì)得到恰當(dāng)?shù)奶幚恚侠淼厥褂卯惓L幚頇C(jī)制,會(huì)讓程序代碼更清晰。 </p><p> 二 關(guān)于JDK和Java異常</p><p> ?。ㄒ唬㎎ava異常定義 </p><p> 早期的編程語(yǔ)言(比如C語(yǔ)言)沒(méi)有異常處理,通常是遇到錯(cuò)誤返回一個(gè)特殊的值或設(shè)定一個(gè)標(biāo)志,并以此判斷是不是有錯(cuò)誤產(chǎn)生。隨著系統(tǒng)規(guī)模的不斷擴(kuò)大,這種錯(cuò)誤處理已經(jīng)成為創(chuàng)建大型可維護(hù)程序
12、的障礙了。于是在一些語(yǔ)言中出現(xiàn)了異常處理機(jī)制,比如在Basic中的異常處理語(yǔ)句“on error goto”,而Java則是在C++基礎(chǔ)上建立了新的異常處理機(jī)制。</p><p> Java通過(guò)面向?qū)ο蟮姆椒ㄟM(jìn)行異常處理,把各種不同的異常進(jìn)行分類(lèi),并提供了良好的接口。這種機(jī)制為復(fù)雜程序提供了強(qiáng)有力的控制方式。同時(shí)這些異常代碼與“常規(guī)”代碼分離,增強(qiáng)了程序的可讀性,編寫(xiě)程序時(shí)也顯得更靈活。 在編譯時(shí)沒(méi)有問(wèn)
13、題的Java源程序,在運(yùn)行期可能還會(huì)發(fā)生錯(cuò)誤,這種錯(cuò)誤就稱(chēng)為異常(Exception)。異常也可認(rèn)為是程序運(yùn)行過(guò)程中違背正常指令流而產(chǎn)生的事件[2]。</p><p> ?。ǘ㎎ava中的異常類(lèi)</p><p> 在Java中,所有的異常都是以類(lèi)對(duì)象的形式存在的。每個(gè)異常都是Throwable類(lèi)或其子類(lèi)的實(shí)例。當(dāng)一個(gè)方法出現(xiàn)異常后便拋出一個(gè)異常對(duì)象,該對(duì)象中包含有異常信息,調(diào)用這個(gè)對(duì)象
14、的方法可以捕獲到這個(gè)異常并進(jìn)行處理[3]。</p><p> Throwable是所有異常的基類(lèi),程序中一般不會(huì)直接拋出Throwable對(duì)象,Exception和Error是Throwable的子類(lèi),Exception下面又有RuntimeException和一般的Exception兩類(lèi)??梢园袹ava異常分為三類(lèi):</p><p> 第一類(lèi)是Error,Error表示程序在運(yùn)行期間
15、出現(xiàn)了十分嚴(yán)重、不可恢復(fù)的錯(cuò)誤,在這種情況下應(yīng)用程序只能終止運(yùn)行,例如Java虛擬機(jī)(JVM)出現(xiàn)錯(cuò)誤。在EJB(Enterprise JavaBean)中將此類(lèi)歸為JVM 異常,這種類(lèi)型的異常由 JVM 拋出。Error是一種uncheckedException(未檢查型異常),編譯器不會(huì)檢查Error是否被處理,在程序中不用捕獲Error類(lèi)型的異常;一般情況下,在程序中也不應(yīng)該拋出Error類(lèi)型的異常。</p><
16、;p> 第二類(lèi)是RuntimeException,在EJB也稱(chēng)為系統(tǒng)異常。RuntimeException是一種未檢查型異常,即表示編譯器不會(huì)檢查程序是否對(duì)RuntimeException作了處理,在程序中不必捕獲未檢查型異常,也不必在方法體聲明拋出RuntimeException類(lèi)。RuntimeException發(fā)生的時(shí)候,表示程序中出現(xiàn)了編程錯(cuò)誤,所以應(yīng)該找出錯(cuò)誤修改程序,而不是去捕獲RuntimeException。&l
17、t;/p><p><b> ……</b></p><p> …… …… </p><p> 圖2-1 Java異常類(lèi)層次圖</p><p> 第三類(lèi)是一般的checkedException, 即已檢查型異常。在EJB中稱(chēng)為應(yīng)用程序異常。已檢查型異常是在編程中使用最多的異常,所
18、有繼承自Exception并且不是RuntimeException的異常都是已檢查型異常,如圖2-1中為Java異常的類(lèi)層次圖。</p><p> Java系統(tǒng)包java.lang、java.util、java.io和java.net中都聲明有標(biāo)準(zhǔn)異常類(lèi)。這些異常類(lèi)以未檢查型異常類(lèi)和已檢查型異常類(lèi)可分為如下:</p><p> 已檢查型異常類(lèi)主要有:</p><p&
19、gt; ?。?)在java.lang中:</p><p> ClassNotFoundException:指定名字的類(lèi)或接口沒(méi)有被發(fā)現(xiàn)。</p><p> CloneNotSupportedException:克隆一個(gè)沒(méi)有實(shí)現(xiàn)Cloneable接口的類(lèi)。</p><p> IllegalAccessException:試圖使用給出了完全路徑信息的字符串加載一個(gè)
20、類(lèi),但當(dāng)前正在執(zhí)行的方法無(wú)法訪(fǎng)問(wèn)指定的類(lèi),原因是該類(lèi)不是public類(lèi)或是在另一個(gè)包中。</p><p> InstantiationException:試圖使用Class的newInstance方法創(chuàng)建一個(gè)對(duì)象實(shí)例,但是,指定的對(duì)象沒(méi)有被實(shí)例化,因?yàn)樗且粋€(gè)接口、抽象類(lèi)或者一個(gè)數(shù)組。</p><p> InterruptedException:當(dāng)前的線(xiàn)程正在等待,而另一個(gè)線(xiàn)程則使用了
21、Thread的interrupt方法中斷了當(dāng)前線(xiàn)程。</p><p> (2)在Java.io中:</p><p> IOException:申請(qǐng)I/O操作沒(méi)有成功。</p><p> EOFException:在輸入操作正常結(jié)束前遇到了文件結(jié)束符。</p><p> FileNotFoundException:在文件系統(tǒng)中,沒(méi)有找到
22、由文件名字符串指定的文件。</p><p> InterruptedIOException當(dāng)前線(xiàn)程正在等待I/O操作的完成,而另一個(gè)線(xiàn)程使用thread的interrupt方法中斷了當(dāng)前線(xiàn)程。</p><p> 未檢查型異常類(lèi)主要有:</p><p> ?。?)在java.lang中:</p><p> ArithmeticExcept
23、ion:表示遇到了算術(shù)的異常問(wèn)題,例如0作為除數(shù)。</p><p> ArrayStoreException:試圖把與數(shù)組類(lèi)型不相符的值存入數(shù)組。</p><p> ClassCastException:試圖把一個(gè)對(duì)象的引用強(qiáng)制轉(zhuǎn)換為不合適的類(lèi)型。</p><p> InderOutOfBoundsException:數(shù)組的下標(biāo)越界。</p>&
24、lt;p> NullPointerException:試圖使用一個(gè)空的對(duì)象引用。</p><p> SecurityException:檢測(cè)到了違反安全的行為。</p><p> ?。?)在java.util中:</p><p> EmptyStaceException:試圖訪(fǎng)問(wèn)一個(gè)空堆棧中的一個(gè)元素。</p><p> NoS
25、uchElementException:試圖訪(fǎng)問(wèn)一個(gè)空向量中的元素。</p><p> ?。ㄈ㎎ava語(yǔ)言規(guī)范對(duì)異常處理的要求</p><p> Java語(yǔ)言規(guī)定必須對(duì)已檢查型異常作處理,編譯器會(huì)對(duì)此作檢查,要么在方法體中聲明拋出已檢查型異常,要么使用catch語(yǔ)句捕獲已檢查型異常進(jìn)行處理,不然不能通過(guò)編譯[2]。已檢查型異常用于以下環(huán)境:</p><p>
26、(1)該異常發(fā)生后是可以被恢復(fù)的,如一個(gè)Internet連接發(fā)生異常被終止后,可以重新連接再進(jìn)行后續(xù)操作。</p><p> ?。?)程序依賴(lài)于不可靠的外部條件,該依賴(lài)條件可能出錯(cuò),如系統(tǒng)I/O。</p><p> (3)該異常發(fā)生后并不會(huì)導(dǎo)致程序處理錯(cuò)誤,進(jìn)行一些處理后可以繼續(xù)后續(xù)操作。</p><p> Java語(yǔ)言規(guī)范中將任何Error的子類(lèi)以及Runti
27、meException的子類(lèi)都稱(chēng)為未檢查型異常。而其它異常都稱(chēng)為已檢查型異常。</p><p> 三 Java異常的處理機(jī)制</p><p> ?。ㄒ唬㎎ava異常處理機(jī)制具體實(shí)現(xiàn)</p><p> 在Java程序運(yùn)行出現(xiàn)異常時(shí),發(fā)生異常的程序段要拋出異常,而運(yùn)行系統(tǒng)負(fù)責(zé)尋找一段代碼來(lái)處理異常。Java語(yǔ)言中,創(chuàng)建一個(gè)異常對(duì)象并將它交給運(yùn)行系統(tǒng)稱(chēng)為拋出一個(gè)異常
28、,又稱(chēng)為異常拋出。</p><p> 在Java中,一個(gè)方法要拋出異常,必須遵循一定的規(guī)定,即所謂的“異常規(guī)范”。異常規(guī)范采用了一個(gè)額外的關(guān)鍵字:throws。要使方法拋出異常,應(yīng)在方法聲明中,位于參變量列表的后面(即throws后面)列舉全部潛在的異常類(lèi)型。</p><p> 假若Java中的某方法可能拋出一個(gè)異常,但程序中沒(méi)有對(duì)其進(jìn)行控制,編譯器會(huì)偵測(cè)到這個(gè)情況,通知程序員必須在此
29、方法內(nèi)進(jìn)行異常控制,或者從方法里拋出一個(gè)異常。通過(guò)遵守異常規(guī)范,Java可在編譯期保證異常處理的正確性。</p><p> 當(dāng)Java拋出一個(gè)異常,程序?qū)膶?dǎo)致異常的代碼處跳出,JVM檢測(cè)尋找和try關(guān)鍵字匹配的處理該異常的catch塊,如果找到,將控制權(quán)交到catch塊中的代碼,然后繼續(xù)往下執(zhí)行程序, 如果沒(méi)有找到處理該異常的catch塊,try塊中發(fā)生異常的代碼不會(huì)被重新執(zhí)行,在所有的finally塊代碼被
30、執(zhí)行和當(dāng)前線(xiàn)程的所屬的ThreadGroup的uncaughtException方法被調(diào)用后,遇到異常的當(dāng)前線(xiàn)程被終止。</p><p> Java異常處理的語(yǔ)句形式如下:</p><p><b> try</b></p><p><b> {</b></p><p> //正常執(zhí)行的代碼可
31、能產(chǎn)生異常</p><p> throw(異常類(lèi)1 e,異常類(lèi)2 e,……異常類(lèi)n e)</p><p><b> }</b></p><p> catch(異常類(lèi)1 e)</p><p><b> {</b></p><p> //異常類(lèi)1的處理代碼</p&
32、gt;<p><b> }</b></p><p> catch(異常類(lèi)2 e)</p><p><b> {</b></p><p> //異常類(lèi)2的處理代碼</p><p><b> }</b></p><p><b&g
33、t; ……</b></p><p> catch(異常類(lèi)n e)</p><p><b> {</b></p><p> //異常類(lèi)n的處理代碼</p><p><b> finally</b></p><p><b> {</b>
34、;</p><p> //執(zhí)行清除工作的語(yǔ)句</p><p><b> }</b></p><p> Java程序運(yùn)行在try塊中,如果產(chǎn)生了異常,則不再運(yùn)行try塊下面的語(yǔ)句,而直接進(jìn)入catch塊中,尋找第一個(gè)與之匹配的異常類(lèi)型。try/catch語(yǔ)句會(huì)自動(dòng)在try塊后面的各個(gè)catch塊中,找出與該異常類(lèi)相匹配的參數(shù)。如果該參數(shù)符合
35、以下三個(gè)條件之一時(shí),則認(rèn)為這個(gè)參數(shù)與產(chǎn)生的異常相匹配[4]。</p><p> (1)參數(shù)與產(chǎn)生的異常屬于同一個(gè)類(lèi)。</p><p> (2)參數(shù)是產(chǎn)生異常的父類(lèi)。</p><p> (3)參數(shù)是一個(gè)接口,產(chǎn)生的異常實(shí)現(xiàn)了這一個(gè)接口。</p><p> 當(dāng)產(chǎn)生的異常找到了第一個(gè)與之相匹配的參數(shù)時(shí),就執(zhí)行這一參數(shù)的catch塊中的Jav
36、a代碼。執(zhí)行完catch塊后,程序恢復(fù)執(zhí)行,但不會(huì)回到異常發(fā)生處繼續(xù)執(zhí)行而是執(zhí)行try/catch結(jié)構(gòu)后面的代碼。</p><p> finally語(yǔ)句可以說(shuō)是為異常處理事件提供的一個(gè)清理機(jī)構(gòu)。一般是用來(lái)關(guān)閉文件或者釋放其他的系統(tǒng)資源作為try/catch/finally結(jié)構(gòu)的一部分,可以沒(méi)有finally塊。如果存在finally塊,無(wú)論try塊中是否發(fā)生異常,是否執(zhí)行過(guò)catch塊,都要執(zhí)行finally塊
37、。用finally塊的一個(gè)好處,就是把方法中所有清除狀態(tài)和關(guān)閉系統(tǒng)文件的語(yǔ)句放在一起,不但避免代碼的重復(fù),更是減少出現(xiàn)遺漏語(yǔ)句,對(duì)于程序以后的修改也較為集中和方便。</p><p> ?。ǘ㎎ava中異常發(fā)生的原因</p><p> 異常發(fā)生有三種原因:</p><p> ?。?)Java虛擬機(jī)檢測(cè)到了非正常的執(zhí)行狀態(tài),這些狀態(tài)可能由三種因素之一引起:</
38、p><p> ①表達(dá)式的計(jì)算違背了Java語(yǔ)言的語(yǔ)義,例如:數(shù)組越界、除數(shù)為0等。</p><p> ②在載入和鏈接Java程序時(shí)出現(xiàn)錯(cuò)誤。</p><p> ?、鄢隽讼到y(tǒng)的資源限制,例如使用了太多的內(nèi)存這些無(wú)法預(yù)知的異常。</p><p> ?。?)Java程序代碼中的throw語(yǔ)句被執(zhí)行。</p><p> (
39、3)發(fā)生異步異常,其可能的原因有Thread類(lèi)的stop方法被調(diào)用;JVM內(nèi)部發(fā)生錯(cuò)誤;運(yùn)行時(shí)庫(kù)出現(xiàn)了內(nèi)部錯(cuò)誤等。</p><p> ?。ㄈ㎎ava異常處理的優(yōu)點(diǎn)</p><p> 在面向過(guò)程的傳統(tǒng)語(yǔ)言中對(duì)程序中可能出現(xiàn)的錯(cuò)誤一般采取:查錯(cuò)、報(bào)錯(cuò)和排錯(cuò)的處理錯(cuò)誤代碼和常規(guī)代碼混雜在一起的方法。比如在C語(yǔ)言(面向過(guò)程的一種編程語(yǔ)言)中輸出流的處理偽代碼是:</p><
40、p> {建立一個(gè)文件輸入流;</p><p> if(建立不成功){ 報(bào)錯(cuò);處理錯(cuò)誤;}</p><p> else { 從輸入流中讀入一個(gè)字符;</p><p> if(讀入不成功){ 報(bào)錯(cuò);處理錯(cuò)誤;關(guān)閉該文件的輸入流</p><p> if(關(guān)閉不成功) { 報(bào)錯(cuò);處理錯(cuò)誤; }</p><p>
41、 else { …… }</p><p><b> }</b></p><p><b> else</b></p><p><b> …… </b></p><p><b> }</b></p><p> 經(jīng)過(guò)這
42、樣的處理,程序可以保證正常地運(yùn)行。但是程序的每一步都要考慮是否會(huì)發(fā)生錯(cuò)誤,出現(xiàn)了錯(cuò)誤又該如何處理的問(wèn)題。這不但使程序代碼的行數(shù)大大增加,而且,處理錯(cuò)誤代碼和正常代碼混雜在一起,使程序流程變得十分復(fù)雜,不利于閱讀。此外,它對(duì)于同一類(lèi)型的錯(cuò)誤也不方便進(jìn)行統(tǒng)一的處理。</p><p> 于上面等價(jià)實(shí)現(xiàn)地面向?qū)ο笳Z(yǔ)言處理異常的偽代碼為:</p><p> try{ 建立一個(gè)文件輸入流;<
43、/p><p> 讀取一個(gè)字符;......;</p><p><b> 關(guān)閉該輸入流;}</b></p><p> catch( 文件輸入流打開(kāi)失敗 ){ 報(bào)錯(cuò);處理錯(cuò)誤;......; }</p><p> catch( 讀入字符失敗 ){ 報(bào)錯(cuò);處理錯(cuò)誤;......}</p><p>&
44、lt;b> ......</b></p><p><b> }</b></p><p> 面向?qū)ο笳Z(yǔ)言的異常處理對(duì)于面向過(guò)程語(yǔ)言處理錯(cuò)誤的方法有三種好處:其一將處理錯(cuò)誤代碼和正常代碼分離;其二能夠?qū)惓Q刂{(diào)用堆棧向上傳播;其三能按異常類(lèi)型和異常對(duì)象分組。</p><p> 四 Java異常處理技術(shù)及其應(yīng)用</
45、p><p><b> ?。ㄒ唬伋霎惓?lt;/b></p><p> 如果有一個(gè)現(xiàn)成(或者已定義)的異常可以使用,則拋出異常很容易。只要滿(mǎn)足以下三點(diǎn):</p><p> (1)找到一個(gè)恰當(dāng)?shù)漠惓n?lèi)</p><p> ?。?)構(gòu)造一個(gè)該類(lèi)的實(shí)例</p><p><b> ?。?)拋出該實(shí)例&l
46、t;/b></p><p> 比如我們經(jīng)常遇到IOException異常發(fā)生,其中它的一個(gè)子類(lèi)是EOFException,就是描述在輸入過(guò)程中碰到一個(gè)未預(yù)期的文件結(jié)尾標(biāo)志,我們拋出該異常的方法如下:</p><p> throw new EOFException ( );</p><p><b> 或者這樣:</b></p
47、><p> EOFException e = new EOFException ( );</p><p> throw e ;</p><p><b> ?。ǘ┎东@異常</b></p><p> 要想捕獲一個(gè)異常,需要設(shè)置一個(gè)try/catch的代碼塊。try塊的最簡(jiǎn)單形式如下:</p><
48、p><b> try {</b></p><p><b> code</b></p><p><b> more code</b></p><p><b> }</b></p><p> catch (ExceptionType e ) {
49、</p><p> handler for this type</p><p><b> }</b></p><p> 如果try塊內(nèi)的任何代碼拋出了由catch塊中指定的異常,則程序跳過(guò)try塊中的其它代碼,程序執(zhí)行catch塊中的處理代碼。假如try塊沒(méi)有任何代碼拋出異常,那么程序會(huì)直接跳過(guò)catch塊的內(nèi)容。當(dāng)然,可以在try塊同時(shí)
50、捕獲多個(gè)異常,并分別對(duì)每種類(lèi)型加以不同的處理。</p><p><b> (三)堆棧幀</b></p><p> 在JDK1.4前,通過(guò)使用Throwable類(lèi)的printStacktrace方法來(lái)獲得堆棧結(jié)構(gòu)的文本描敘?,F(xiàn)在,可以通過(guò)調(diào)用getStackTrace方法來(lái)獲得一個(gè)StackTraceElement對(duì)象的數(shù)組,通過(guò)研究該數(shù)組,就可以分析程序運(yùn)行情況。
51、例如:</p><p> Throwable t = new Throwable ( );</p><p> StackTraceElement[ ] frames = t.getStackTrace ( );</p><p> For ( int i= 0;i<frames.length;i++) </p><p> 使用St
52、ackTraceElement類(lèi)提供的方法獲取文件名以及當(dāng)前執(zhí)行的代碼行行號(hào)的方法,同樣,它還提供獲取類(lèi)名、方法名的方法。而toString方法可以產(chǎn)生一個(gè)格式化字符串,其中包含那些獲得的信息。</p><p> 以下程序StackTest.java輸出一個(gè)遞歸調(diào)用方法的堆棧情況。</p><p> import java.util.*;</p><p>
53、import javax.swing.*;</p><p> public class StackTest</p><p><b> {</b></p><p> /** 返回 n! = 1 * 2 * . . . * n 的結(jié)果 */</p><p> public static in
54、t factorial (int n)</p><p><b> {</b></p><p> System.out.println ("factorial (" + n + "):" ) ;</p><p> Throwable t = new Throwable( );</p>
55、<p> StackTraceElement[ ] frames = t.getStackTrace();</p><p> for ( int i = 0 ;i < frames.length; i++ )</p><p> System.out.println( frames[ i] );</p><p><b> int
56、r ;</b></p><p> if (n <= 1) r = 1;</p><p> else r = n * factorial(n - 1); // 遞歸調(diào)用factorial()方法</p><p> System.out.println("return " + r);</p><p>
57、;<b> return r;</b></p><p><b> }</b></p><p> public static void main(String[] args)</p><p><b> {</b></p><p> String input = JOpt
58、ionPane.showInputDialog( "請(qǐng)輸入一個(gè)整數(shù):" );</p><p> int n =Integer.parseInt(input);</p><p> factorial(n);</p><p> System.exit( 0 ); //退出程序</p><p>
59、;<b> }</b></p><p><b> }</b></p><p> 由于需要從標(biāo)準(zhǔn)輸入中獲取整數(shù)數(shù)字,Integer.ParseInt(input)方法可能會(huì)產(chǎn)生java.lang.NumberFormatException異常。運(yùn)行程序時(shí)界面:</p><p> 圖3-1 輸入界面</p>
60、;<p> 如果我們要實(shí)現(xiàn)遞歸方法factorial(3),通過(guò)getStackTrace方法可以查看程序運(yùn)行的過(guò)程。其結(jié)果為如下:</p><p> 圖3-2 遞歸方法factorial(3)的輸出結(jié)果</p><p> 而這個(gè)程序可能產(chǎn)生的一個(gè)異常是NumberFormatException異常。當(dāng)異常產(chǎn)生后,JVM調(diào)用該異常處理。其運(yùn)行界面如下:</p
61、><p> 圖3-3 輸入一個(gè)產(chǎn)生異常的數(shù)據(jù)</p><p> 返回到控制臺(tái)的結(jié)果為描述該異常:</p><p> 圖3-4 輸入異常數(shù)據(jù)時(shí)在控制臺(tái)產(chǎn)生的結(jié)果</p><p><b> ?。ㄋ模┳远x異常</b></p><p> 由于在Java中,異常也被看成是對(duì)象,而且異常和一
62、般的對(duì)象沒(méi)有什么不同。因此,任何類(lèi)都可以定義它自己的異常,并用throw語(yǔ)句引發(fā)它們。其中,throw語(yǔ)句由帶有一個(gè)對(duì)象的關(guān)鍵字throw組成,這個(gè)對(duì)象應(yīng)該是Exception或其子類(lèi)的一個(gè)實(shí)體對(duì)象。要注意的是,當(dāng)執(zhí)行了一條throw語(yǔ)句后,就不會(huì)執(zhí)行該語(yǔ)句之后的任何代碼了。</p><p> 通常每個(gè)異常類(lèi)提供一個(gè)默認(rèn)的構(gòu)造器以及一個(gè)包含詳細(xì)信息的構(gòu)造器。使用Throwable的toString方法會(huì)輸出該詳
63、細(xì)信息,這個(gè)方法對(duì)代碼調(diào)試是很有用處。</p><p> 例如創(chuàng)建這樣的異常類(lèi):</p><p> class FileFormatException extends IOException {</p><p> public FileFormatException ( ) { </p><p><b> }<
64、;/b></p><p> public FileFormatException ( ) {</p><p> super ( gripe) ;</p><p><b> }</b></p><p><b> }</b></p><p> String re
65、adData ( BufferedReader in ) throws FileFormatException {</p><p><b> ……</b></p><p> while ( ……)</p><p><b> {</b></p><p> if ( ch==-1) /
66、/EOF標(biāo)記,即文件結(jié)尾</p><p><b> {</b></p><p> if (n<len) </p><p> throw new FileFormatException ( );</p><p> //拋出自定義的異常類(lèi)FileFormatException</p><
67、p><b> }</b></p><p><b> ……</b></p><p><b> }</b></p><p><b> return s;</b></p><p><b> } </b></p>
68、;<p> ?。ㄎ澹╆P(guān)于圖形界面程序的異常捕獲</p><p> 對(duì)于一個(gè)非圖形界面的程序而言,如果一個(gè)異常沒(méi)有被捕獲,則程序會(huì)終止運(yùn)行并且在控制臺(tái)輸出一條包含異常類(lèi)型以及堆棧內(nèi)容的信息。而對(duì)于具有圖形界面的程序(包含applet以及應(yīng)用程序),也會(huì)輸出這些錯(cuò)誤信息,但是程序會(huì)返回用戶(hù)界面外層循環(huán)中去。</p><p> 下面我們從一個(gè)有趣的程序-顏色調(diào)和板來(lái)討論圖形界面
69、程序處理異常的情況。</p><p> 在SwingColorTest.java(源代碼見(jiàn)附錄)中,程序可以根據(jù)我們輸入紅色、綠色、藍(lán)色(RGB)、亮度、飽和度和色度值來(lái)調(diào)節(jié)顏色。整個(gè)程序除了可能會(huì)產(chǎn)生RuntimeException異常外,這個(gè)程序還會(huì)產(chǎn)生NumberFormatException異常。當(dāng)然這是已檢查型異常。</p><p> 下面我們來(lái)看它在JVM中的運(yùn)行情況:&l
70、t;/p><p> 圖4-1 輸入正常數(shù)據(jù)時(shí)的顏色調(diào)和板</p><p> 當(dāng)我們改變”紅色”值為非法的一個(gè)輸入,比如:“AB”時(shí),其運(yùn)行結(jié)果為如下:</p><p> 圖4-2 輸入一個(gè)產(chǎn)生異常的數(shù)據(jù)</p><p> 顏色未變化,好像程序發(fā)生邏輯錯(cuò)誤似的(沒(méi)有按照我們希望的去運(yùn)行)其實(shí)程序已將控制權(quán)轉(zhuǎn)到控制中心去了,這個(gè)圖形還處于
71、初始化階段(在輸入“AB”前)。在控制中心我們發(fā)現(xiàn)如下一些異常發(fā)生描述:</p><p> 圖4-3 異常產(chǎn)生后返回到控制臺(tái)的說(shuō)明</p><p> 這說(shuō)明發(fā)生了NumberFormatException(數(shù)字格式異常)異常后,并沒(méi)有繼續(xù)往下執(zhí)行代碼。由于數(shù)字格式異常為已檢查型異常,直接調(diào)用系統(tǒng)的方法處理了。</p><p> JVM報(bào)告程序發(fā)生了數(shù)字格式異
72、常產(chǎn)生,并將其具體的情況報(bào)告給用戶(hù)。但是,是不是這個(gè)程序不能再接受正常的輸入數(shù)據(jù)運(yùn)行呢?還是必須要重新啟動(dòng)才能運(yùn)行?</p><p> 我們將“紅色”值由“AB”改為“200”后發(fā)現(xiàn)顏色改變,這說(shuō)明該程序還能運(yùn)行。結(jié)果如下圖:</p><p> 圖4-4 將產(chǎn)生異常的輸入數(shù)據(jù)更改后的顏色調(diào)和板</p><p> 可見(jiàn)當(dāng)輸入了正常的數(shù)據(jù)后,程序就像第一次運(yùn)行一
73、樣,可以正確的顯示顏色了。我們得到的結(jié)論是:部分Java圖形界面程序發(fā)生異常后不需要重新初始化,依舊可以運(yùn)行,但必須不再有異常發(fā)生。</p><p> 五 Java異常處理基本原則</p><p> 合理使用Java異常機(jī)制可以使程序健壯而清晰,但是,Java異常處理機(jī)制也常常會(huì)被錯(cuò)誤地使用,下面就討論一些關(guān)于使用異常的原則:</p><p> (一)不要忽
74、略已檢查型異常</p><p><b> 注意下面的代碼:</b></p><p><b> try {</b></p><p> method1(); //method1拋出Exception A</p><p><b> }</b><
75、;/p><p> catch(Exception A) //捕獲Exception A</p><p><b> {</b></p><p> e.rintStackTrace( ); //打印捕獲異常</p><p><b> }</b></p>
76、<p> 上面的代碼似乎沒(méi)有什么問(wèn)題,捕獲異常后將異常打印,然后繼續(xù)執(zhí)行。事實(shí)上在catch塊中對(duì)發(fā)生的異常情況并沒(méi)有作任何處理。雖然程序能夠繼續(xù)執(zhí)行,但是由于這里的操作已經(jīng)發(fā)生異常,將會(huì)導(dǎo)致以后的操作不能按照預(yù)期的情況發(fā)展下去,可能導(dǎo)致兩個(gè)結(jié)果。</p><p> 一種情況是這里的異常導(dǎo)致在程序中別的地方拋出一個(gè)異常,這會(huì)使程序員在調(diào)試時(shí)感到迷惑,因?yàn)樾碌漠惓伋龅牡胤讲⒉皇浅绦蛘嬲l(fā)生問(wèn)題的地方
77、,也不是發(fā)生問(wèn)題的真正原因。</p><p> 另外一種情況程序繼續(xù)運(yùn)行,并得出一個(gè)錯(cuò)誤的輸出結(jié)果,這種問(wèn)題更加難以捕捉,因?yàn)楹芸赡馨阉?dāng)成一個(gè)正確的輸出。</p><p> 那么應(yīng)該如何處理呢?一般有四個(gè)選擇:處理異常,進(jìn)行修復(fù)以讓程序繼續(xù)執(zhí)行;重新拋出異常,在對(duì)異常進(jìn)行分析后發(fā)現(xiàn)這里不能處理它,那么重新拋出異常,讓調(diào)用者處理;將異常轉(zhuǎn)換為用戶(hù)可以理解的自定義異常再拋出,這時(shí)應(yīng)該注意
78、不要丟失原始異常信息;不要捕獲異常。</p><p> 因此,當(dāng)捕獲一個(gè)未檢查型異常時(shí),必須對(duì)異常進(jìn)行處理;如果認(rèn)為不必要在這里作處理,就不要捕獲該異常,在方法體中聲明方法拋出異常,由上層調(diào)用者來(lái)處理該異常。</p><p> (二)不要一次捕獲所有的異常</p><p> 我們常見(jiàn)如下關(guān)于異常處理的代碼:</p><p><b&
79、gt; try</b></p><p><b> {</b></p><p> method1(); //method1拋出ExceptionA</p><p> method2(); //method2拋出ExceptionB</p><p
80、> method3(); //method3拋出ExceptionC</p><p><b> }</b></p><p> catch(Exception e) //捕獲所有異常</p><p><b> { …… }</b></p><p
81、> 代碼中使用一個(gè)catch子句捕獲了所有異常,看上去很簡(jiǎn)潔,一個(gè)代碼段就捕獲了全部的異常。但是這里有兩個(gè)潛在的缺陷,一是對(duì)try塊中拋出的每種異常,很可能需要不同的處理和恢復(fù)措施,而由于這里只有一個(gè)catch塊,分別處理就不能實(shí)現(xiàn)。二是try塊中還可能拋出RuntimeException,代碼中捕獲了所有可能拋出的RuntimeException而沒(méi)有作任何處理,掩蓋了編程的錯(cuò)誤,會(huì)導(dǎo)致程序難以調(diào)試。</p>&
82、lt;p> 我們應(yīng)該處理為以下的代碼:</p><p><b> try</b></p><p><b> {</b></p><p> method1();</p><p> method2();</p><p> method3();
83、</p><p><b> }</b></p><p> catch (ExceptionA e)//分別捕獲和處理三種異常</p><p><b> { …… }</b></p><p> catch (ExceptionB e)</p><p><
84、b> { …… }</b></p><p> catch (ExceptionC e)</p><p><b> { …… }</b></p><p> (三)使用finally塊釋放資源</p><p> 關(guān)鍵字finally保證程序使用任何方式離開(kāi)try塊,finally塊中的語(yǔ)句都會(huì)被執(zhí)
85、行。當(dāng)程序中使用了外界資源,如數(shù)據(jù)庫(kù)連接、文件等,將釋放這些資源的代碼寫(xiě)入finally塊中是很好的處理方式。</p><p> 必須注意的是,在finally塊中不能拋出異常。Java異常處理機(jī)制保證在任何情況下必須先執(zhí)行finally塊然后再離開(kāi)try塊,因此在try塊中發(fā)生異常的時(shí)候,Java虛擬機(jī)先轉(zhuǎn)到finally塊執(zhí)行finally塊中的代碼,finally塊執(zhí)行完畢后,再向外拋出異常。如果在fin
86、ally塊中拋出異常,try塊捕捉的異常就不能拋出,外部捕捉到的異常就是finally塊中的異常信息,而try塊中發(fā)生的真正的異常堆棧信息則丟失了。</p><p> Connectioncon = null;</p><p><b> try {</b></p><p> con=dataSource.getConnection();&
87、lt;/p><p><b> //拋出數(shù)據(jù)庫(kù)異常</b></p><p><b> }</b></p><p> catch(SQLException e ) {</p><p><b> ……</b></p><p> //捕獲異常進(jìn)行一些處理后
88、再將數(shù)據(jù)庫(kù)異常拋出給調(diào)用者處理</p><p><b> throw e;</b></p><p><b> }</b></p><p><b> finally {</b></p><p><b> try {</b></p>&l
89、t;p> con.close();</p><p><b> }</b></p><p> catch(SQLException e) {</p><p> e.printStackTrace();</p><p><b> ……</b></p><p>&l
90、t;b> }</b></p><p><b> }</b></p><p> 由于con為null,finally塊有異常發(fā)生,從而使try塊中發(fā)生的異常堆棧信息丟失。其調(diào)用者會(huì)得到如下信息:</p><p> Java.lang.NullPointerExceptionat</p><p>
91、 myPackage.MyClass.method1(methodl.Java:266)</p><p> (四)異常不能影響對(duì)象的狀態(tài)</p><p> 異常產(chǎn)生后不能影響對(duì)象的狀態(tài),這是異常處理中的一條重要規(guī)則。一個(gè)函數(shù)中發(fā)生異常后,對(duì)象的狀態(tài)應(yīng)該和調(diào)用這個(gè)函數(shù)之前保持一致,以確保對(duì)象處于正確的狀態(tài)中。</p><p> 如果對(duì)象是不可變對(duì)象(指調(diào)用構(gòu)造函
92、數(shù)創(chuàng)建后就不能改變的對(duì)象),即創(chuàng)建后沒(méi)有任何方法可以改變對(duì)象的狀態(tài),那么異常發(fā)生后對(duì)象狀態(tài)肯定不會(huì)改變。如果是可變對(duì)象,必須在編程中注意保證異常不會(huì)影響對(duì)象狀態(tài)。</p><p> 有三個(gè)方法可以做到異常不能影響對(duì)象地狀態(tài):</p><p> ?。?)將可能產(chǎn)生異常的代碼和改變對(duì)象狀態(tài)的代碼分開(kāi),先執(zhí)行可能產(chǎn)生異常的代碼,如果產(chǎn)生異常,就不執(zhí)行改變對(duì)象狀態(tài)的代碼。</p>
93、<p> ?。?)對(duì)不容易分離產(chǎn)生異常代碼和改變對(duì)象狀態(tài)代碼的方法,定義一個(gè)recover方法,在異常產(chǎn)生后調(diào)用recover方法修復(fù)被改變的類(lèi)變量,恢復(fù)方法調(diào)用前的類(lèi)狀態(tài)。</p><p> ?。?)在方法中使用對(duì)象的拷貝,這樣當(dāng)異常發(fā)生后,被影響的只是拷貝,對(duì)象本身不會(huì)受到影響。</p><p> (五)注意丟失(或忽略)的異常</p><p>
94、在程序設(shè)計(jì)中,可以丟失(忽略)一些異常,但是為了以后更好地維護(hù)代碼,最好不要丟失異常。比如下面的代碼:</p><p> public void method2( ) {</p><p><b> try</b></p><p><b> {</b></p><p><b> …
95、…</b></p><p> method1( ); //method1進(jìn)行了數(shù)據(jù)庫(kù)操作</p><p><b> }</b></p><p> catch( SQLException e )</p><p><b> {</b></p>
96、<p><b> ……</b></p><p> //捕獲數(shù)據(jù)庫(kù)異常后將該異常封裝為</p><p> //MyException后重新拋出</p><p> throw new MyException(“發(fā)生了數(shù)據(jù)庫(kù)異常:" +e.getMessage);</p><p><b
97、> }</b></p><p><b> }</b></p><p> public void method3( ) {</p><p><b> try</b></p><p><b> {</b></p><p>
98、method2( ); //調(diào)用method2(),拋出MyException</p><p> catch (MyException e)</p><p><b> {</b></p><p> e.printStackTrace( );</p><p><b> ……
99、</b></p><p><b> }</b></p><p><b> }</b></p><p> 在method2的代碼中,try塊捕獲method1拋出的數(shù)據(jù)庫(kù)異常SQLException后,拋出了新的自定義異常MyException。這段代碼是似乎沒(méi)有什么問(wèn)題,但在控制臺(tái)的輸出卻是:</p
100、><p> MyException:發(fā)生了數(shù)據(jù)庫(kù)異常:對(duì)象名稱(chēng)“MyTable"無(wú)效</p><p> atMyClass.method2(MyClass.Java:232)</p><p> atMyClass.method3(MyClass.Java:255)</p><p> 原始異常SQLException的信息丟失了,
101、這里只能看到method2里面定義的MyException的堆棧情況,而method1中發(fā)生的數(shù)據(jù)庫(kù)異常的堆棧則看不到。</p><p> 如何排錯(cuò)呢?只有在method1的代碼行中一行行去尋找數(shù)據(jù)庫(kù)操作語(yǔ)句。JDK的開(kāi)發(fā)者們也意識(shí)到了這個(gè)情況,在JDK1.4.1中,Throwable類(lèi)增加了兩個(gè)構(gòu)造方法,public Throwable ( Throwablecause)和public Throwable (
102、 Stringmessage, Throwablecause ),在構(gòu)造函數(shù)中傳入的原始異常堆棧信息將會(huì)在printStackTrace方法中打印出來(lái)。但在JDK1.3中就只能靠程序員來(lái)實(shí)現(xiàn)打印原始異常堆棧信息了。實(shí)現(xiàn)過(guò)程也很簡(jiǎn)單,只需要在自定義的異常類(lèi)中增加一個(gè)原始異常字段,在構(gòu)造函數(shù)中傳入原始異常,然后重載printStackTrace方法,首先調(diào)用類(lèi)中保存的原始異常的printStackTrace方法,然后再調(diào)用super.pri
103、ntStackTrace方法就可以打印出原始異常信息了??梢赃@樣定義前面代碼中出現(xiàn)的MyException類(lèi):</p><p> public class MyException extends Exception</p><p><b> {</b></p><p> public SMException ( Throwable ca
104、use )</p><p><b> //構(gòu)造函數(shù)</b></p><p><b> {</b></p><p> this.cause1=cause;</p><p><b> }</b></p><p> public MyExceptio
105、n ( Strings ,Throwable cause )</p><p><b> {</b></p><p><b> super(s);</b></p><p> this.cause1=cause;</p><p><b> }</b></p>
106、<p> //重載printStackTrace方法,打印出原始異常堆棧信息</p><p> public void printStackTrace()</p><p><b> {</b></p><p> if(cause1!=null)</p><p><b> {</b
107、></p><p> cause1.printStackTrace();</p><p><b> }</b></p><p> super.printStackTrace(s);</p><p><b> }</b></p><p> public voi
108、d printStackTrace(PrintStream s)</p><p><b> {</b></p><p> if(cause1!=null)</p><p><b> {</b></p><p> cause1.printStackTrace(s);</p>
109、<p><b> }</b></p><p> super.printStackTrace(s);</p><p><b> }</b></p><p> public void printStackTrace( PrintWriter s )</p><p><b&g
110、t; {</b></p><p> if(cause1!=null)</p><p><b> {</b></p><p> cause1.printStackTrace(s);</p><p><b> }</b></p><p> super.pr
111、intStackTrace(s);</p><p><b> }</b></p><p> private Throwable cause1;</p><p><b> }</b></p><p> (六)不要同時(shí)使用異常機(jī)制和返回值來(lái)處理異常</p><p>
112、我們可能會(huì)使用類(lèi)似下面一段代碼:</p><p><b> try{</b></p><p> doSomething( );</p><p><b> }</b></p><p> catch(MyException e){</p><p> if(e.getEr
113、rcode==-1)</p><p><b> { …… }</b></p><p> if(e.getErrcode==-2)</p><p><b> { …… }</b></p><p><b> …… </b></p><p> 假如過(guò)
114、一段時(shí)間再來(lái)閱讀這段代碼,你很難弄明白程序的意思?;旌鲜褂肑ava異常處理機(jī)制和返回值使程序的異常處理部分變得混亂,并難以理解。</p><p> 在程序中,如果有多種不同的異常情況,就應(yīng)該定義多種不同的異常,而不要像上面代碼那樣。綜合使用Exception和返回值。處理應(yīng)該如下:</p><p><b> try {</b></p><p&g
115、t; doSomething( );</p><p> //doSomething()拋出MyExceptionA和MyExceptionB</p><p><b> }</b></p><p> catch(MyExceptionA e) //捕獲異常分別進(jìn)行處理</p><p><b>
116、 { …… }</b></p><p> catch(MyExceptionB e)</p><p><b> { …… }</b></p><p> (七)不要讓try塊過(guò)于龐大</p><p> 有人習(xí)慣用一個(gè)龐大的try塊包含所有可能產(chǎn)生異常的代碼,這樣有兩個(gè)壞處:一是閱讀代碼的時(shí)候,在try塊
117、冗長(zhǎng)的代碼中,不容易知道到底是哪些代碼會(huì)拋出哪些異常,不利于代碼維護(hù);二是使用try捕獲異常是以程序執(zhí)行效率為代價(jià)的,將不需要捕獲異常的代碼包含在try塊中,影響了代碼執(zhí)行的效率。因此,在Java程序中最好將try塊編寫(xiě)得簡(jiǎn)潔些。</p><p><b> 六 結(jié)束語(yǔ)</b></p><p> Java是一種面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言,Java的異常處理機(jī)制非常出色
118、。Java中的所有異常都是從基礎(chǔ)類(lèi)Throwable里繼承而來(lái)的,所以可確保我們得到的是一個(gè)通用接口。丟棄一個(gè)錯(cuò)誤的異常后,Java異常規(guī)范是在編譯期間檢查并執(zhí)行的。被取代的方法必須遵守那一方法的基礎(chǔ)類(lèi)的異常規(guī)范。</p><p> Java可丟棄指定的異?;蛘邚闹付ó惓Q苌鰜?lái)的其他異常。這樣一來(lái),運(yùn)用try/catch/finally異常處理機(jī)制,最終得到的是更為“健壯”的異??刂拼a。Java異常處理為大
119、的程序項(xiàng)目帶來(lái)很好的健壯性。</p><p> 當(dāng)然,在寫(xiě)本論文時(shí),由于對(duì)Java的學(xué)習(xí)沒(méi)達(dá)到深入、精通程度,掌握J(rèn)ava異常處理技術(shù)也不是很全面,故而論文中對(duì)Java圖形程序的異常處理方面和Java異常處理機(jī)制具體實(shí)現(xiàn)的討論仍有不足之處有待以后改進(jìn)。</p><p><b> 致謝</b></p><p><b> 參考文獻(xiàn)&
120、lt;/b></p><p> [1]Bloch J.Effective. Java Programming Language Guide.北京:機(jī)械工業(yè)出版社,2001.</p><p> [2]Cay S.Horstmann .Core Java 2(第6版) .北京:機(jī)械工業(yè)出版社,2004.</p><p> [3]Rogers Cadenhea
121、d ,Laura Lemay.Teach Yourself Java 2 In 21`days.北京:人民郵電出版社,2004.</p><p> [4]朱福喜,唐曉軍.Java程序設(shè)計(jì)技巧與實(shí)例.北京:人民郵電出版社,2004.</p><p> [5]譚浩強(qiáng),程龍,楊海蘭,吳功宜.Java編程技術(shù).北京:人民郵電出版社,2003.</p><p> [6]
122、彭晨陽(yáng).Java實(shí)用系統(tǒng)開(kāi)發(fā)指南. 北京:機(jī)械工業(yè)出版社,2003.</p><p> [7]Java 2 SDK1.5.0 Standard Edition Documentation</p><p> [8]http://Java.sun.com/j2se/index.jsp</p><p> [9]黃聰明.精通Java 2 程序設(shè)計(jì).北京:清華大學(xué)出版社
123、,2004.</p><p> [10]Kalthy Sierra,Bert Bates.Java 2學(xué)習(xí)指南.北京:人民郵電出版社,2004.</p><p> [11]耿祥義.Java基礎(chǔ)教程.北京:清華大學(xué)出版社,2004.</p><p> [12]朱福喜.Java程序設(shè)計(jì)技巧與開(kāi)發(fā)實(shí)例.北京:人民郵電出版社,2004.</p><
124、p> [13]謝小樂(lè).J2EE經(jīng)典實(shí)例詳解.北京:人民郵電出版社,2003.</p><p> [14]Y.Daniel Liang.Java語(yǔ)言程序設(shè)計(jì)(第三版).北京:機(jī)械工業(yè)出版社,2005. </p><p> [15]Bruce Eckel.Java編程思想. 北京:機(jī)械工業(yè)出版社,2005.</p><p><b> 附
溫馨提示
- 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ù)僅提供信息存儲(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 基于java的畢業(yè)設(shè)計(jì)論文
- 畢業(yè)設(shè)計(jì)(論文)-基于java技術(shù)的論壇(bbs)
- 基于java的酒店管理系統(tǒng)畢業(yè)設(shè)計(jì)論文
- 基于java技術(shù)的網(wǎng)上招聘系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)論文(doc畢業(yè)設(shè)計(jì)論文)
- 畢業(yè)設(shè)計(jì)(論文)--基于java的郵件系統(tǒng)
- 基于java網(wǎng)絡(luò)聊天系統(tǒng)畢業(yè)設(shè)計(jì)論文
- 基于java的網(wǎng)上投票系統(tǒng)(doc畢業(yè)設(shè)計(jì)論文)
- 優(yōu)秀畢業(yè)設(shè)計(jì)論文+源碼基于java的圖書(shū)館管理系統(tǒng)畢業(yè)設(shè)計(jì)(論文)
- java考試系統(tǒng)畢業(yè)設(shè)計(jì)(論文)
- 畢業(yè)設(shè)計(jì)--基于java的游戲設(shè)計(jì)
- java坦克大戰(zhàn)畢業(yè)設(shè)計(jì)論文
- 基于java的論壇bbs的實(shí)現(xiàn)(doc畢業(yè)設(shè)計(jì)論文)
- 基于java的cs模式網(wǎng)絡(luò)聊天室的畢業(yè)設(shè)計(jì)(doc畢業(yè)設(shè)計(jì)論文)
- 基于java的圖書(shū)館管理系統(tǒng)畢業(yè)設(shè)計(jì)(論文)
- 畢業(yè)設(shè)計(jì)(論文)+手機(jī)游戲開(kāi)發(fā)-java畢業(yè)論文
- 基于java手機(jī)游戲畢業(yè)設(shè)計(jì)
- java畢業(yè)設(shè)計(jì)論文 網(wǎng)上購(gòu)物書(shū)店設(shè)計(jì)
- java學(xué)生管理系統(tǒng)畢業(yè)設(shè)計(jì)論文
- java畢業(yè)設(shè)計(jì)論文中期報(bào)告
- 畢業(yè)設(shè)計(jì)論文 java 24點(diǎn)游戲設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論