异常(try...catch...finally、throws、throw)
當出現(xiàn)程序無法控制的外部環(huán)境(文件不存在,文件內(nèi)容損壞,網(wǎng)絡(luò)不可用等)問題時,java就會用異常對象來描述。
Java中用2種方法處理異常:
1、 在發(fā)生異常的地方直接處理。
2、 將異常拋給調(diào)用者,讓調(diào)用者處理。
?
異常的分類:
1、 檢查性異常:java.lang.Exception 程序正確,但因為外在的環(huán)境條件不足引發(fā)
2、 運行期異常:java.lang.RuntimeException 這意味著程序出現(xiàn)bug,如數(shù)組越界,除以0等,這類異常需要更改程序來避免
3、 錯誤:java.lang.Error 可能源于程序的bug,但更可能源于環(huán)境問題,如內(nèi)存耗盡、系統(tǒng)崩潰、動態(tài)鏈接失敗等,這種錯誤無法恢復或不可能捕獲,會導致程序中斷,錯誤在程序中無序處理,而由運行環(huán)境處理。
?注意:進行異常捕獲時所有父類異常的catch塊都應該排在子類異常catch塊的后面(先處理小異常,再處理大異常)。
?
訪問異常信息:如果程序需要在catch塊中訪問對象的相關(guān)信息,可以通過調(diào)用catch后異常形參的方法來獲取
1、 getMessage():返回異常的詳細描述字符串。
2、 printStackTrace():將異常的跟蹤棧信息輸出到標準錯誤輸出。
3、 printStackTrace(PrintStream s):將該異常的跟蹤棧信息輸出到指定輸出流。
4、 getStackTrace():返回該異常的跟蹤棧信息。
?
?
利用finally回收資源:
??? 程序在try里打開了一些物理資源(如數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接等),這些物理資源必須顯示回收。因為java的垃圾回收機制不會回收任何物理資源,只能回收堆內(nèi)存中對象所占用的內(nèi)存。為了保證一定能回收try中打開的物理資源,異常處理機制提供了finally塊,不管是否出現(xiàn)異常,finally塊總會被執(zhí)行。異常處理語法結(jié)構(gòu):只有try塊是必須的,catch和finally是可選的,但至少出現(xiàn)其中之一,catch可有多個。
以下情形,finally將不會被執(zhí)行
1、 finally塊中發(fā)生異常
2、 程序所在線程死亡
3、 在前面的代碼中用了System.exit()
4、 關(guān)閉cpu
注意:一旦finally中使用了return或throw語句,將會導致try塊、catch塊中的return、throw語句失效。
(當java程序執(zhí)行try塊、catch塊時遇到了return或throw語句,這兩個語句會導致方法立即結(jié)束,所以系統(tǒng)并不會立即執(zhí)行者兩個語句,而是去尋找是否有finally塊,如果沒有,程序立即執(zhí)行return或throw語句,方法終止;如果有finally,系統(tǒng)立即執(zhí)行finall塊,只有當finally塊執(zhí)行完成后系統(tǒng)才跳回來執(zhí)行try、Catch塊里的return、throw,如果finally里也使用了return或throw等導致方法終止的語句,則finally塊已經(jīng)終止了方法,系統(tǒng)將不會跳回執(zhí)行try、catch塊里的任何代碼。)
?
?
使用throws聲明拋出異常:throws只能在方法簽名中使用,可以聲明拋出多個異常類,以逗號隔開。
使用throws的情況:
1、當前方法不知道應該如何處理這種類型的異常。
2、該異常應該由上一級調(diào)用者處理。
拋出的異常將講給JVM處理。處理方法是:打印異常跟蹤棧信息并終止程序運行,這就是程序一道異常后自動結(jié)束的原因。
注意:使用throws拋出異常時有一個限制,就是方法重寫時:子類方法中聲明拋出的異常類型應該是父類拋出異常類型的子類或相等。
使用Checked異常至少存在兩大不便之處:
1、對于程序中Checked異常,java要求必須顯式的捕獲并處理該異常或顯式聲明拋出,這就愛增加了編程的復雜度。
2、如果在方法中顯式聲明拋出Checked異常麻將會導致方法簽名與異常耦合,如果方法是重寫父類的方法,則該方法能拋出的異常還受被重寫方法所拋出的異常限制。
?
?
使用throw拋出異常:
java允許程序自行拋出異常,由throw來完成。其拋出的不是異常類,而是一個異常實例,每次只能拋出一個異常實例。
如果throw拋出的異常時checked異常,則該throw語句要么處于try塊里,顯式捕獲該異常,要么放在一個帶有throws聲明的方法中;如果throw語句拋出的異常時runtime異常,則該語句無須放在try塊里或帶throws拋出的方法中,程序可以顯式使用try...catch來捕獲,并處理異常,也可以完全不理會該異常,把該異常交給該方法調(diào)用者處理。
?
?
自定義異常類:需要繼承Exception基類,如希望自定義Runtime異常則需繼承RuntimeException基類,定義異常時要提供兩種構(gòu)造器,無參的和帶一個字符串的,這字符串作為該異常對象的詳細說明,即getMessaga方法的返回值。
?
?
總結(jié):
1、處理異常,對異常采用合適的修補,然后繞過異常發(fā)生的地方繼續(xù)執(zhí)行;或者用別的數(shù)據(jù)進行計算以代替期望的方法返回值;或者提示用戶重新操作等,總之,對于checked異常,程序應該盡量采用修復。
2、重新拋出異常,把當前運行環(huán)境下能做的事情盡量做完,然后進行異常轉(zhuǎn)譯,把異常包裝成當前層的異常,重新拋出給上層調(diào)用者。
3、在合適的層處理異常。如果當前層不清楚如何處理異常,就不要在當前層使用catch來捕獲異常,直接使用throws拋出異常,讓上層調(diào)用者來負責處理異常。
?
轉(zhuǎn)載于:https://www.cnblogs.com/wyl-study/archive/2012/02/14/2351308.html
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的异常(try...catch...finally、throws、throw)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 字符“23.00”转成int型!Inpu
- 下一篇: 主键设计原则