posts - 82, comments - 269, trackbacks - 0, articles - 1
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Java提供了兩類主要的異常:runtime exception和checked exception。checked 異常也就是我們經常遇到的IO異常,以及SQL異常都是這種異常。對于這種異常,JAVA編譯器強制要求我們必需對出現的這些異常進行catch。所以,面對這種異常不管我們是否愿意,只能自己去寫一大堆catch塊去處理可能的異常。
           
             但是另外一種異常:runtime exception,也稱運行時異常,我們可以不處理。當出現這樣的異常時,總是由虛擬機接管。比如:我們從來沒有人去處理過NullPointerException異常,它就是運行時異常,并且這種異常還是最常見的異常之一。
           
              以前一直沒仔細想過出現運行時異常了系統會怎樣工作,最近在一個模塊排錯時,才無意中發現了系統是如何處理運行時異常。出現運行時異常后,系統會把異常一直往上層拋,一直遇到處理代碼。如果沒有處理塊,到最上層,如果是多線程就由Thread.run()拋出,如果是單線程就被main()拋出。拋出之后,如果是線程,這個線程也就退出了。如果是主程序拋出的異常,那么這整個程序也就退出了。運行時異常是Exception的子類,也有一般異常的特點,是可以被Catch塊處理的。只不過往往我們不對他處理罷了。
           
              也就是說,你如果不對運行時異常進行處理,那么出現運行時異常之后,要么是線程中止,要么是主程序終止。如果程序的退出剛好是你期望的結果,那就萬事OK了。
           
             但最近我在項目卻遇的問題,恰恰是這因為沒有對運行時異常進行處理,而導致程序在運行一小段時間后就當了。事情是這樣的,由于寫程序時我對多線程的并發處理不太會,也就把一個模塊寫成了單線程的,由它來循環處理一個數據隊列。但沒想到隊列里面的數據有一些與預期的格式不一樣,處理這樣的數據時,程序就拋出了運行時異常。由于沒有對異常進行處理,這個異常也就拋到了Thread.run()。最后這個處理線程肯定是被終止了,隊列里面的數據也就不會再有程序去處理了。這個結果顯然不是我想要的,隊列里面出現異常數據了,正常的處理應該是把異常數據舍棄,然后記錄日志。不應該由于異常數據而,影響下面對正常數據的處理啊。
           
              所以最后我在程序的循環處理模塊,里面加了一個catch處理,來撲捉所有的異常,決不讓這個處理線程退出,要知道我的所有數據還要依靠他來處理呢 (^_^ )。在這個場景這樣處理可能是一個比較好的應用,但并不代表在所有的場景你都應該如此。如果在其它場景,遇到了一些錯誤,如果退出程序比較好,這時你就可以不太理會運行時異常,或者是通過對異常的處理顯式的控制程序退出。
           
             知道了虛擬機怎么處理運行時異常,也更進一步理解了Sping對Hibernate的封裝了。由于Hibernate是和數據庫打交道,所以總是要拋出一些亂七八糟的checked異常,平時我們根本不想catch這些異常。因為這些異??偸前汛a弄的亂亂的,搞的到處都是try{} catch(){}塊,并且常常加了catch塊,也并不能把程序從異常中恢復過來(異常處理的目標之一就是為了把程序從異常中恢復出來)。為了通過編譯器的檢查,程序員被迫加上了catch塊,往往這些catch并沒有發揮他應有的作用,反而帶來了很大的不便。所以Spring對Hibernate封裝時就把Hibernate的異常進行了封裝,全部封裝成運行時異常了。也就是Spring來撲捉Hibernate拋出的異常,然后Spring把異常轉換成Spring自己定義的運行時異常再拋出。這樣我們在編碼時使用Spring來調用Hibernate時,可以不用catch塊來處理一些不必要的異常。當然你確實要是想處理,也可以通過添加cathc塊去處理異常。不過這個時候,你的Catch就要撲捉運行時異常了,而不是一般的checked異常了。
             
             上面的觀點,僅僅是一點經驗參考,完全是一家之言,如果有寫錯的地方請指教(email: flyfoxs+blog0528@gmail.com, blog:http://blog.openj.cn)。runtime exception和checked exception這兩種異常可能并不太好理解,如果不太理解的話,可以參考下面的文獻。


          注:以前把此文章發布于我的MSN的Blog,后來Blog搬家了,就把此文章再發一次到這個地方.

          評論

          # re: 運行時異常"也要撲捉(JAVA版)(原創)   回復  更多評論   

          2007-04-25 13:58 by zfqjava
          覺得有些RuntimeException確實不能忽略,在編碼的過程中一個明顯的
          例子就是NumberFormatException,幾乎所有的NumberFormatException
          都需要處理,盡管這個類的父類IllegalArgumentException一般不需要處理。

          # re: 運行時異常"也要撲捉(JAVA版)(原創)   回復  更多評論   

          2007-04-25 14:55 by BeanSoft
          是呀, 盡量還是多做些預防性編碼, 例如好多時候都是假定傳入的參數不是 null, 但是很多時候就是 null ... java 這個地方又沒有強制手段.

          # re: 運行時異常"也要撲捉(JAVA版)(原創)   回復  更多評論   

          2007-04-25 16:56 by wenlin
          雖然一直這么用,但是沒有像樓主這樣研究過。

          # re: 運行時異常"也要撲捉(JAVA版)(原創)   回復  更多評論   

          2007-04-26 15:21 by 王凌華
          有同樣的體會。

          # re: 運行時異常"也要撲捉(JAVA版)(原創)   回復  更多評論   

          2007-04-26 15:32 by mack
          讀了,有收獲。^_^

          # re: 運行時異常"也要撲捉(JAVA版)(原創) [未登錄]  回復  更多評論   

          2007-07-21 00:14 by andy
          受益非淺,謝謝

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 荣昌县| 阳高县| 镇江市| 富川| 雷山县| 乐山市| 黄平县| 定日县| 论坛| 霍城县| 满城县| 吴江市| 青浦区| 苏州市| 左权县| 临西县| 水富县| 万州区| 郑州市| 松江区| 西畴县| 武冈市| 临城县| 湟中县| 翼城县| 营山县| 盐城市| 永昌县| 赞皇县| 偃师市| 醴陵市| 泽库县| 大城县| 二连浩特市| 龙井市| 象山县| 信宜市| 桐城市| 法库县| 比如县| 剑河县|