<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的  回復  更多評論   

    主站蜘蛛池模板: 国产精品亚洲午夜一区二区三区| 亚洲日韩av无码| 亚洲欧美成人av在线观看| 韩国日本好看电影免费看| 免费一级做a爰片性色毛片| 国产免费久久久久久无码| 狠狠色伊人亚洲综合成人| 国产电影午夜成年免费视频| 男男gay做爽爽的视频免费| 日本高清免费网站| 中文在线观看免费网站| 性xxxx黑人与亚洲| 国产亚洲人成网站在线观看不卡| 久久久高清免费视频| 国产精品亚洲四区在线观看| 亚洲精品无码专区2| 一级毛片aaaaaa视频免费看| 亚洲精品日韩中文字幕久久久| 国产精品免费观看| 国产精品成人免费观看| 亚洲日韩精品无码AV海量| 亚洲国产精品va在线播放| 四虎影视永久免费观看地址| 97在线视频免费公开观看| 中美日韩在线网免费毛片视频| 亚洲午夜精品一区二区公牛电影院 | a毛片免费播放全部完整| 亚洲乱理伦片在线观看中字| 久久亚洲精品成人777大小说| 最近2022中文字幕免费视频| 成人免费视频一区二区| 77777亚洲午夜久久多喷| 亚洲综合一区二区国产精品| 亚洲日本在线观看视频| 四虎影视www四虎免费| 亚欧在线精品免费观看一区| 中文在线免费视频| 国产免费福利体检区久久| 日日摸日日碰夜夜爽亚洲| 国产精品久久久亚洲| 亚洲色偷偷狠狠综合网|