程序员基本功08异常捕捉的陷阱
1、使用finally正確地關閉資源
在實際開發中,經常需要 在程序中打開一些物理資源,如數據庫連接、網絡連接、磁盤文件等,打開這些物理資源后必須顯示關閉,否則將引起資源泄露。JVM的垃圾回收機制屬于Java內存管理的一部分,它只負責回收堆內存中分配出來的內存,至于程序中打開的物理資源,垃圾回收機制無能為力。
finally{if(oos!=null){try{oos.close(); }catch(Exception ex){ex.printStackTrace(); } } }使用finally塊來關閉物理資源,保證關閉操作總會被執行;
關閉每個資源之前首先保證引用該資源的引用變量不為null;
為每個物理資源使用單獨try...catch塊關閉資源,保證關閉資源時引發的異常不會影響其他資源的關閉
2、finally遇到return的處理
只要JVM不退出,finally代表總是會被執行的代碼塊,因此finally塊總是用來關閉物理資源,從而保證程序物理資源總能被正常關閉。
當Java程序執行try塊、catch塊時遇到了return語句,return語句會導致該方法立即結束。系統執行完return語句后,并不會立即結束該方法,而是去尋找該異常處理流程中是否包含finally塊,若果沒有,方法終止,返回相應的返回值。如果有finally塊,系統立即執行finally塊---只有當finally塊執行完成后,系統才會再次跳回來根據return語句結束方法。如果finally使用return語句來結束方法,系統不會調回去執行try塊、catch塊里任何代碼。
同理,當程序執行try塊、catch塊時遇到throw語句時,throw語句會導致該方法立即結束,系統執行throw語句并不會立即拋異常,而是尋找該異常處理流程中是否包含finally塊,如果沒有,程序拋異常;如果有,系統執行finally塊,只有finally塊執行完成后,系統才會再次跳出來拋異常。如果finally使用return結束方法,系統不會跳回去執行try塊、catch塊去拋異常。
3、finally遇到System.exit()的處理
當Syatem.exit(0)被調用時,虛擬機退出前執行兩項清理工作:
- 執行系統中注冊的所有關閉鉤子;(安全)
- 如果程序調用了System.runFinaluzerOnExit(true):那么JVM會對所有還為結束的對象調用Finalize。(此種行為危險)
4、catch塊只能先捕捉子類異常
對于Java異常捕捉,每個try塊至少需要一個或多個catch塊或一個finally塊,絕不能只有try。當Java運行環境接收到異常對象時,系統會根據catch(XxxException e)語句決定使用哪個異常分支來處理程序引發的異常。當程序進入負責異常處理的catch塊時,系統生成的異常對象ex將會被傳給catch(XxxException e)語句的異常形參,從而允許catch塊通過該對象來訪問異常的詳細信息。通過提供catch塊,無需在異常處理中使用if、switch判斷異常類型,但依然可以針對不同異常類型提供相應的處理邏輯,從而提供細致、條里的異常處理邏輯。通常情況下,try塊被執行一次,則try塊后只有一個catch會被執行,絕不能有多個catch塊被執行。除非在循環中使用了continue開始下一次循環,下一次循環又重新運行了try塊,導致catch塊被執行。
異常處理機制中排在前面的catch(XxxExpection)塊總是會優先獲得執行的機會,一次對catch塊的排列順序是有要求的:先捕捉小的異常,再捕捉大的異常。Exception是所有異常類的根父類,因此應把Exception塊排在所有catch塊的最后面。
5、只有catch可能拋出的異常
不要在程序中使用異常機制,更不要使用異常處理機制來代替流程控制,對于程序中各種能夠預知的情況,應該盡量處理,不要盲目使用異常捕捉來代替流程控制。
6、catch塊內應做實際的修復
如果知道如何修復指定異常,應該在catch塊內盡量修復異常,當該異常被修復后,可以再次調用該方法;如不知道如何修復,也沒有任何修復,千萬不要再次調用可能導致該異常的方法。否則會形成無限遞歸,最終導致java.lang.StackOverflowError錯誤非正常結束。
7、只能聲明拋出所實現方法允許聲明拋出異常的交集
Java語言規定,子類重寫父類方法時,不能聲明拋出比父類方法類型更多、范圍更大的異常。也就是說,子類只能聲明父類方法中所聲明拋出的異常子類。當一個子類同時實現多個接口時,其只能拋出倆個接口聲明異常的交集或者不寫。
總結
以上是生活随笔為你收集整理的程序员基本功08异常捕捉的陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员基本功10栈和队列
- 下一篇: 程序员基本功 07 面向对象的陷阱