<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Change Dir

    先知cd——熱愛生活是一切藝術的開始

    統計

    留言簿(18)

    積分與排名

    “牛”們的博客

    各個公司技術

    我的鏈接

    淘寶技術

    閱讀排行榜

    評論排行榜

    該如何良好的實踐Java中的Exception機制

    首先,我先聲明一點,我討論的僅限于互聯網數據產品,當然可能會涉及到一些其他的抽象,但是所有的結論不代表能復用到所有場景。

     

            幾乎每個Java程序員都清楚知道Java的異常和錯誤機制,無論是在面試過程中,還是在學習中,你看到Exception,無非就是了解一下繼承關系、子類、和Error的關系等等。當然這些知識點是基礎,那么在實踐中,用到了嗎?你確定你使用Exception時沒有偷懶?我的經驗告訴我,良好的使用Exception能讓你的程序bug更少,或者至少能保證你的程序更容易被理解和跟蹤。

     

            先回到老的知識點吧——Java的異常機制,我們知道Java里的異常是完全繼承Throwable的,正如java doc里注釋的,無論你throw的還是JVM throw的,抑或是你想catch的,都必須繼承Throwable。我這里幫助大家糾正的第一個點就是:java.lang.Throwable是一個class,不是一個interface,千萬別被名字欺騙。優秀的程序員有好的命名習慣,當Java程序員默認認為帶有-able后綴的都該是接口時, Josh Bloch給大家上了一課——Throwable就是類。回到正題,Throwable有兩大子類,一個是java.lang.Error,一個是java.lang.ExcpetionError是錯誤,一般多用于系統異常和底層錯誤,Error拋出就會導致程序終止;而Exception是異常,有程序引起,又分為受檢的checked和非受檢的unchecked(不知道哪本書這么翻譯的來著),受檢的異常是普通異常,就是你需要catch的來打日志或者補救的(這種做法叫吞掉異常),非受檢的多數是RuntimeException,就是運行時異常,這類異常不建議catch,因為這個是程序bug,需要被人發現,所以建議拋出引起程序終止。Blah~blah~ 這些都是老生常談的話題,需要深入的點是有幾個:

     

            第一,Error是建議到系統級別的錯誤的,包括虛擬機的,我們常見的就是java.lang.VirtualMachineError,這是一個JVM級別的抽象Error,如果你覺得沒見過?那么不用奇怪,它的兩個兒子你肯定見過:OutOfMemoryErrorStackOverflowErrorError其實真沒好說的,一般情況不建議捕獲,程序員也用的較少,但是你看很多基礎框架或者系統軟件,都是有自定義Error的,所以當你的工作層次或者范圍你能確定比較底層時,其實是可以自定義一些Error來控制程序的錯誤的。我這樣說可能也不是很好理解,換個簡單的話:你的架構設計中需要考慮到異常的處理,那么首先要對異常定級別,如果有可能有偏底層的異常時,或者是本不該出現且不建議用戶(多數是依賴你的庫進行開發的其他程序員)捕獲時,定義為Error是個不錯的選擇。當然也不是說做上層開發的程序員就不能使用Error,只要你設計合理,你可以在必要時拋出Error來終止程序——比如提醒你的老板再不加薪就Error到死:)

     

            第二,Exception分兩類這事幾乎人人皆知,受檢的異常往往是web后端開發或者服務開發自定義的業務異常比如BizServiceException或者常見的DAOException,這些異常在開發定義時總是直接extends Exception,而忽視了究竟這些異常我們對它們的期望是什么,這里我想強調一點,我們在業務系統架構中考慮到異常機制,自定義的異常不是為了有異常而定義異常,一定對它本身是有期望的。我們對異常的一個基本期望是異常究竟該被誰捕獲,如果被你的服務下游捕獲,那么這必須是一個受檢的異常,如果是系統自身需要,那么這個我個人認為是分階段設計的,在初期,也就是未發布狀態,這些Exception應該總是被拋出的,因為這樣可以快速的讓測試和質量控制人員發現系統崩潰的點。在發布階段,異常可能需要被內部消化,這時受檢異常就要提供給業務系統,讓業務開發自行捕獲異常。當然,好的系統架構可能會把Exception作為一個內部可見外部不可見的內容,而基于此完全封裝一套error code對外,這應該算是比較友好的做法了,也是很多API設計時的標準規范。畢竟對外部透明,不要讓用戶看到你的Exception,這是非常友好的做法。

     

            第三,關于catch,就針對上面的第二點講,吞異常這事不是沒人干過,我們往往擔心系統錯誤而一個try catch 捕獲所有Exception,有的甚至不夠,還升一級,捕獲Throwable,這應該是最糟糕的代碼設計(但不幸的是在我現在開發的系統和曾經開發過的業務系統中,這類代碼非常普遍)。開發人員不應該因為時間緊、趕進度等接口而忽視Exception,就拿最上層的業務開發舉例,開發可能會調用各類服務、訪問數據庫、訪問緩存和文件系統等等,而這些服務必然包含了各種異常,而catch一個Exception,試圖通過吞噬異常保護系統或者頁面正常訪問,而打日志到后臺,通過分析日志來偷偷的解決bug……說起來真是汗毛倒豎。我的觀點:如果有錯誤,那么讓它盡早暴露出來,我們應該通過盡量多的測試和優化來避免錯誤,而不是偷偷的隱藏。事實也證明,日志里大量的NPE或者其他RuntimeException存在,但是無人問津,“系統不是好好的嗎?”,“頁面不是沒問題嗎”這樣的說辭可以讓開發看起來毫無責任,但是這為系統長期的維護和后續的擴展都帶來了無盡的煩惱和坑。

     

             綜上,我個人的經驗告訴我幾點對待Exception的方法:

            1,花時間了解涉及到的每個服務和方法所可能拋出的異常。事實往往是理解異常的關系和機制其實不花時間,了解后再開發,你會比別人知道更多的異常點,這能保證你程序的健壯性;

            2,無論你在服務開發還是服務使用層級,都要嘗試或者想到封裝異常,提供友好錯誤設計的方案,最簡單的是自定義一個業務Exception來封裝。

            3,不要在你的方法開始try,結束時catch,這防御性太強了,很美品位。

            4,前三點可能都是錯的,因為我自己也沒有完全實踐:)

    posted on 2015-02-26 15:19 changedi 閱讀(7545) 評論(1)  編輯  收藏 所屬分類: Java技術

    評論

    # re: 該如何良好的實踐Java中的Exception機制 2015-03-06 23:51 gaochang

    有時間整個體子或是封裝一個組件出來唄。
    一般都是繼承exception,然后做一些設置,或者用spring的  回復  更多評論   

    主站蜘蛛池模板: 大地影院MV在线观看视频免费| 亚洲国产成人爱av在线播放| 亚洲一二成人精品区| 免费精品国自产拍在线播放 | 亚洲精品乱码久久久久蜜桃 | 国精无码欧精品亚洲一区| 麻豆va在线精品免费播放| 日韩免费无砖专区2020狼| 国产精品亚洲自在线播放页码| 日本免费人成视频在线观看| 亚洲精品无码Av人在线观看国产| 男女啪啪免费体验区| 免费国产真实迷j在线观看| 亚洲精华国产精华精华液网站| 99久久免费国产精品特黄| 亚洲成a人片在线观看中文!!!| 日韩中文字幕免费视频| 亚洲av中文无码乱人伦在线播放 | 亚洲成av人在片观看| 在线观看亚洲免费视频| 国产精品四虎在线观看免费| 亚洲码欧美码一区二区三区| 成年女人免费视频播放体验区| 久久精品国产亚洲AV蜜臀色欲| 99视频全部免费精品全部四虎| 亚洲成aⅴ人片在线影院八| ww在线观视频免费观看| 亚洲精品国产情侣av在线| 91九色视频无限观看免费| 亚洲理论片在线中文字幕| 日本视频一区在线观看免费| 亚洲国产午夜精品理论片| 久久久久久免费视频| 中文无码亚洲精品字幕| 全免费a级毛片免费看不卡| 亚洲高清一区二区三区电影| 国产黄色片在线免费观看| 羞羞视频免费网站入口| 亚洲真人日本在线| 韩国免费A级毛片久久| 国产AV无码专区亚洲Av|