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

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

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

    人在江湖

      BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
      82 Posts :: 10 Stories :: 169 Comments :: 0 Trackbacks

    這篇和前面的 總結java的interface和abstract class 一樣。跳過最基礎語法不聊,只說一些比較tricky的東西和一些好的practice.

     

    語法:

    Exception繼承自Throwable. Throwable還有一個兒子是Error,但是一般用不到。不過有些二百五面試官喜歡問回字有幾種寫法,所以還是要知道有Error這回事的。Exception分為checked和unchecked兩種。

     

    java的checked exception一直是個很有爭議的東西。Thinking in Java的作者Bruce, C#的設計者和Martin Fowler都對checked exception持質疑態度。 一個典型的反對理由是:"We felt it was unrealistic to require the programmer to provide handlers in situations where no meaningful action can be taken." 這話太實惠了。寫方法給caller調用,怎么能magically知道調用這個方法的所有caller,能夠處理特定的異常呢?

     

    關于Exception有個比較基本的語法是,子類override的方法如果聲明拋出exception, 只能拋出父方法聲明的exception,或者那個exception的子類。需要注意的是,“回”字還有一種寫法,對于constructor來說沒有這個限制,子類可以拋出任意exception。父類構造函數聲明的exception,子類也必須聲明,而且子類的構造函數不能捕捉父類聲明的exception. 這個想想也容易理解,父類構造出錯了,兒子居然能處理還把自己生出來了,沒老子哪來的兒子?當然你可以抬杠說老子戴綠帽子的情況。

     

    實踐:

    1. 盡量不要在構造函數里做復雜的操作,盡量不要讓constructor拋出exception。如果在構造函數里拋出exception,需要用nested try block. 如下:

       1: public class Cleanup { 
       2:   public static void main(String[] args) { 
       3:     try { 
       4:       InputFile in = new InputFile("Cleanup.java"); 
       5:       try { 
       6:         String s; 
       7:         int i = 1; 
       8:         while((s = in.getLine()) != null) 
       9:           ; // Perform line-by-line processing here... 
      10:       } catch(Exception e) { 
      11:         System.out.println("Caught Exception in main"); 
      12:         e.printStackTrace(System.out); 
      13:       } finally { 
      14:         in.dispose(); 
      15:       } 
      16:     } catch(Exception e) { 
      17:       System.out.println("InputFile construction failed"); 
      18:     } 
      19:   } 
      20: } 

    而不是用finally來做清理工作。

     

    2. exception的一個基本使用原則是,exception不是設計用來控制程序flow的。 這是很簡單的道理,還是引用effective java的一個例子吧

       1: // Horrible abuse of exceptions. Don't ever do this!
       2: try {
       3: int i = 0;
       4: while(true)
       5: range[i++].climb();
       6: } catch(ArrayIndexOutOfBoundsException e) {
       7: }

    我真正要說明的是,上面說的原則很對,但是走到極端就不對了。有的人為了 不用exception控制程序flow, 就寫一大堆的if…else語句試圖考慮各種情況,正好前不久有同事說了個笑話,我覺得可以輔助解釋這個問題。

    =============================

    某日,老師在課堂上想考考學生們的智商,就問一個男孩“樹上有十只鳥,開槍打死一只,還剩幾只?”

    男孩反問“是無聲手槍,還是其他沒有聲音的槍么?”

    “不是。”

    “槍聲有多大?”

    “80~100分貝。”

    “那就是說會震的耳朵疼?”

    “是。”

    “在這個城市里打鳥犯不犯法?”

    “不犯。”

    “您確定那只鳥真的被打死啦?”

    “確定.”老師已經不耐煩了,”拜托,你告訴我還剩幾只就行了,OK?”

    “OK.鳥里有沒有聾子?”

    “沒有。”

    “有沒有鳥智力有問題,呆傻到聽到槍響不知道飛的?”

    “沒有,智商都在200以上!”

    “有沒有關在籠子里的?”

    “沒有。”

    。。。

    ==============================

    后面還有一堆“例外”情況。我們寫程序總不能真寫成

    if(鳥是聾子)

    else if(鳥是傻子)

    else if(鳥是瘸子)

    原則應該是,如果一些情況確實是 “例外情況”,就用exception處理吧。不要很勤奮地寫一堆defensive的判斷。我們不會有故事里的小男孩兒思維那么滴水不漏的。別把Java程序退回c語言了。另一個例子是FileNotFoundException, java I/O沒有讓你每次用文件都提前調用exists()檢查一下,我想原因不光是 檢查文件的那一毫秒文件存在,run到下一步的時候,下一毫秒文件消失了,Sun沒覺得你人品那么壞吧。理念仍然是,如果你覺得文件肯定存在,你就直接用吧,一旦不存在,你再另外當成異常情況處理。不要讓一堆if…else弄臟了程序。

     

    3. exception有個典型用法是在方法體中,進行參數合法性校驗

     

       1: public BigInteger mod(BigInteger m) {
       2: if (m.signum() <= 0)
       3: throw new ArithmeticException("Modulus <= 0: " + m);
       4: ... // Do the computation
       5: }

    也有很多人用assert語句判斷, 比如 Assert.notNull(object)。手動拋exception可以拋特定的類型,assert語句更方便。可以根據實際情況取舍。

     

    4. 既然上面說了checked exception本身是java設計不太合理的地方。我傾向于說,應該及時把checked exception translate成unchecked. 我知道exception的處理原則有一條是,如果你不知道怎么處理它,就不要捕捉它。 對于checked exception來說,它總force你去處理,太討厭了。如果caller不知道怎么處理,留著給更上層的程序處理…底層的程序都不會處理,一般來說上層的程序就更不知道該怎么處理了,那還不如在盡量底層的調用中,要么處理它(這種情況很少,打log之類的算不上“處理”),要么就轉成RuntimeException拋上來, 消滅掉checked exception帶來的burden. 注意:translate exception的過程中,不要扔了原來的exception, 而要把它放在exception constructor的argument里, new RuntimeException(e)。這是很基本的東西,不多說。

     

    5. 不要吞exception. 這個太基礎,不多說。

     

    6. 見到exception要把它記log里,而不是簡單print stack一下,log4j的api有可以接受Throwable作為參數的。

     

    7. 每層拋出來的exception要對當前這一層有意義,比如persistence層出問題,UI上你告訴客戶hibernate的session關閉了,不能繼續load數據了,客戶還以為你的程序怎么跟狗熊一樣還會冬眠的。即使是UI層以下,底層exception,比如sql exception也不要爬到domain層里處理

     

    8. apache commons的lang包里有ExceptionUtils類,玩兒exception最好把這個工具揣口袋里。

    9.exception是設計的一部分, 但它不同于API的設計。通常我們設計API的時候,不會設計一個函數destroyBaghdad(),通常我們會寫destroyCity(Baghdad)。這樣做的目的是為了重用。換句話說,你設計API的時候,總是裝作忘了use case(caller), 而去寫適合復用的API, 盡管上面的例子use case就是destroy Baghdad, 你還是要寫更general的destroyCity函數,然后把城市的名字作為參數傳進去.但exception的設計不應該用同樣的思路做,因為你很難料想到復用的情況下,你聲明的exception是不是總能在任何情況下都得到妥善的處理。舉個例子,這是我臨時想的例子,形象但是科技太超前了。我們寫一個print()程序給打印機A,print()的時候沒有紙可以拋一個checked NoPaperException,這時候exceptino的處理程序可以自動加載紙(目前這么高級的功能正在貝爾實驗室研發呢)。也許有新型的打印機B總是先加紙,后打印,那么永遠也不存在NoPaperException。如果打印機是老式打印機C,不會自動加載紙,見到NoPaterException也無計可施,沒法處理。checked exception的哲學是,強制讓caller處理它。從上面的例子看,只有A打印機需要并能夠處理NoPaperException。 B打印機不需要處理exception。C打印機沒能力處理exception. 所以,|“需要并能夠”處理是個太嚴格的限制,一般情況下不應該用checked exception. 我們可以讓print聲明拋出unchecked exception. 提醒caller可以處理它,但是對于不應該處理它的caller也不強制去處理它。

    posted on 2011-02-22 00:12 人在江湖 閱讀(9424) 評論(5)  編輯  收藏 所屬分類: java

    Feedback

    # re: 總結java的exception 2011-02-22 21:43 人在江湖
    很奇怪,這篇blog點擊率高的離譜,你們是怎么看到這個blog的?我之前的blog每天最多一千出頭的點擊率,這篇24小時內到四千多了,真的困惑。  回復  更多評論
      

    # re: 總結java的exception 2011-02-22 23:01 HappyGao
    @人在江湖
    是從首頁看到的呀。  回復  更多評論
      

    # re: 總結java的exception[未登錄] 2011-02-24 16:29 llq
    樓主很幽默,我是初學者,多多向你學習  回復  更多評論
      

    # re: 總結java的exception 2011-02-25 13:24 Lu Han
    好文!
    最近灑家剛剛被問到回字的寫法哦!  回復  更多評論
      

    # re: 總結java的exception 2011-02-28 09:10 mashiguang
    你都罵了250了,我懂不敢告訴你是“茴”而非“回”了,管他3721,我就孔乙己一回,相信樓主明白我是好意提醒。  回復  更多評論
      

    主站蜘蛛池模板: 亚洲精品成人网站在线观看 | 亚洲av永久无码精品秋霞电影秋 | 久久久久亚洲AV片无码下载蜜桃| 97精品免费视频| 在线精品自拍亚洲第一区| 国产成人A人亚洲精品无码| www.黄色免费网站| 国产黄色免费观看| 97久久国产亚洲精品超碰热| 免费一级毛片在级播放| 99re6热视频精品免费观看| 国产成人亚洲综合在线| 久久夜色精品国产噜噜噜亚洲AV | 国产精品亚洲片在线观看不卡| 国产桃色在线成免费视频| 成年网在线观看免费观看网址 | 亚洲中文字幕无码亚洲成A人片| 久久99亚洲综合精品首页| 无码精品A∨在线观看免费| 一级特黄aaa大片免费看| 亚洲18在线天美| 亚洲αv久久久噜噜噜噜噜| 国产成人aaa在线视频免费观看 | 成年女人A毛片免费视频| 77777午夜亚洲| 亚洲AV日韩AV高潮无码专区| 亚洲av无码成人精品区| 国产卡一卡二卡三免费入口| 中文字幕免费在线看电影大全 | 久久这里只精品国产免费10| 丰满亚洲大尺度无码无码专线| 中文字幕亚洲色图| 亚洲精品无码Av人在线观看国产| 妞干网免费观看视频| 最近中文字幕完整免费视频ww| xxxxxx日本处大片免费看| 亚洲熟妇AV日韩熟妇在线| 亚洲第一二三四区| 亚洲AV无码乱码国产麻豆穿越| 亚洲狠狠爱综合影院婷婷| 麻豆成人精品国产免费|