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

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

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

    愛睡覺的小耗子
    ——等待飄雪的日子...努力,努力,再努力!
    posts - 9,  comments - 33,  trackbacks - 0
    轉載于:http://www.tangrui.net/2007/01/09/difference-between-java-and-dotnet-on-exception-handling/
     
    關于 Java 和 .Net 優劣的爭論一直在繼續,而在異常處理方面體現得最為激烈,因為他們之間的差異是如此明顯。.Net 晚于 Java 出現,那么 Java 對 .Net 就理應起到很重要的借鑒作用,但是偉大的 Anders Hejlsberg 為什么沒有繼續 Java 的實現方式,而是另辟蹊徑,這是一個非常值得研究的問題。因為我們要承認一個真理:正確的東西大家都是一樣的正確,錯誤的卻各有個的錯誤。可以肯定這不可 能是 Anders 的疏忽,那么他的道理究竟何在,或者說他們之間究竟有什么區別?

          在你能耐下心來看完這篇帖子之前,我想要明確告訴你一個結論:Java 和 .Net 在異常處理的本質上是沒有區別的。

    一、Java 是如何處理異常的

          如果一個 Java 方法要拋出異常,那么需要在這個方法后面用 throws 關鍵字定義可以拋出的異常類型。倘若沒有定義,就認為該方法不拋出任何異常。如果從方法的入口和出口的角度去考慮一下這個規范,我們知道參數可以認為是方 法的入口(當然某些情況下也可以是出口),而返回值則是方法的出口,這是在程序正常執行的情況下,數據從入口入,出口出。要是程序非正常執行,產生異常又 當如何? 被拋出的異常應該如何從方法中釋放出來呢? Java 的這種語法規范就如同給異常開了一個后門,讓異常可以堂而皇之“正確”地從方法里被拋出。

          這樣的規范決定了 Java 語法必須強行對異常進行 try-catch。設想一下,對于以下的方法簽名:

    public void foo() throws BarException { ... }

    暗含了兩方面的意思:第一,該方法要拋出 BarException 類型的異常;第二,除了 BarException 外不能拋出其他的異常。而正是這第二點的緣故,我們要如何保證沒有除 BarException 之外的任何異常被拋出呢? 很顯然,就需要 try-catch 其他的異常。也就是說,一般情況下,方法不拋出哪些異常就要在方法內部 try-catch 這些異常。

          Java 這樣的機制既有優點,也有缺點。先來說說優點:

    • 很顯然,這種規范是由 Java 編譯器決定的。倘若 Java 程序的入口點 main() 方法沒有任何異常拋出,就是說要在 main() 方法內部,即整個程序內部捕捉所有的異常,否則將無法通過編譯。這樣編譯器保證了程序對每個異常都有相應的計劃和處理,不會有未處理的異常被泄露到虛擬機 中,導致程序意外中斷或退出,也就是增強了程序的健壯性。當然,Java 有 RuntimeException 的概念,這樣的異常仍然可以隨時被拋出到虛擬機中。
    • 強行 try-catch 要求把異常作為程序設計的一部分看待。就如同方法的參數和返回值一樣,在編寫一個方法時,要結合上下文做出通盤的考慮和打算。雖然異常是所謂的“意外情況”,但是這些“例外”理應是被我們全部了解并處理的。
    • 方便調試。異常理應在正確的位置被捕捉。當異常發生時,我們能更清楚的了解到其來源和相應處理程序的位置,而免去了在整個調用棧中摸索的麻煩。
    • 在不借助任何文檔的情況下,從方法簽名就可以知曉應該對哪些異常進行處理。

          Java 異常處理機制的這些優點也直接導致了他的致命弱點:將程序變得異常繁復。往往一個簡單的程序,功能代碼寥寥幾行,而異常處理部分卻占用了程序的絕大部分篇 幅;同時導致縮進深度加深,既不利于書寫,也不利于閱讀。另外他的強行 try-catch 需要程序員有更高深的造詣,能夠通盤考慮異常處理設計問題,這個在程序開始之初或者對于初學者是一個不小的門檻。這往往會阻礙其推廣與發展,因為低水平初 學者的信心往往因此而受到打擊。然而對于高手來說,編譯器是否能幫助他們找到未被處理的異常只是一個方便與否的問題,只要在編寫方法時注意了異常處理,即 便沒有編譯器的支持,情況也不會糟糕太多。反而倒是由于要遵循這樣復雜的異常處理規范,以至于大多數人都可能為了圖一時方便,對異常的基類型 Exception 或 Throwable 進行籠統地捕捉,這樣做的危害就是那些你無法處理的異常被溺死在處理程序中,(按照異常處理原則,我們應該只捕捉那些可以被處理或恢復的異常,而把其他的 異常繼續拋出。至于這樣做的優勢,以及不這樣做所帶來的問題,不是一兩句能夠說清楚,這里就不展開討論了。)導致程序的不穩定和不確定。既沒有發揮 Java 語法在這方面的優勢,反而增加了憂患。

    二、.Net 是如何處理異常的

          一句話概括 .Net 的異常處理方式就是隨心所欲。沒有人要求你一定要拋出異常,也更沒有人要求你一定要捕捉異常。未被捕捉的異常會被以 Unhandled Exception 的形式拋出到虛擬機中。在此我就要先解決一下文章開頭提到的問題,為什么說 Java 和 .Net 這兩種異常處理機制在本質上是相同的。可以從兩個方面來考慮:

    1. 默認情況下。Java 在默認情況下 main() 方法是不拋出異常的,正如前面所說的,這要求所有的異常都必須在 main() 方法內部被捕捉;而 .Net 則沒有這種約束,他的 Main() 以至于整個應用程序中的任何一個方法對異常都是完全開放的。這樣來看,這兩者剛好是對立互補的。
    2. 非默認情況下。Java 可以通過在 main() 方法后面加 throws 關鍵字使得整個應用程序對異常開放;而 .Net 則可以通過給應用程序域(Application Domain)的 UnhandledException 事件添加委托達到捕捉所有異常的目的,很顯然這又是對立互補的。

    因此,就好像一個是“正反”,一個是“反正”,加在一起“正反反正”都是一樣的,對于達到控制異常的目錄來說,是沒有區別的。

          很多 Java 愛好者都鄙視 .Net 的這種行為,一方面他令程序變得不夠健壯,因為默認情況下沒有強制的辦法要求所有的異常都被處理,或被正確處理;另外,他為調試增加了困難,不借助文檔或 代碼你將無法了解到一個方法可能拋出什么異常,而當一個異常被拋出的時候,同時異常處理代碼又寫得不夠完善,你將不得不仔細查看整個調用棧來確定異常出現 的位置,而對于這一點 Java 默認是強制的。

          但是 Anders 的想法總是有道理的。

    1. .Net 代碼寫起來非常容易。這是對于初學者,或者那些只是想實現一些測試性小功能的人而言,你完全沒有必要考慮太多異常處理的細節,你要的就是寫代碼,然后讓他 跑起來。這樣的簡單性無疑是你希望看到的,這樣的簡單性無疑更有利于 .Net 在市場上的推廣。由于他在這方面并沒有什么理論上的漏洞,也就仍然適合構建龐大的項目,只是感覺沒有那么舒服罷了。
    2. 一定程度上增加了程序的安全性。難道不捕捉異常可以被成為是安全的嗎?這個話也許要從另外一方面來想,前面說過,有些 Java 程序員(絕對不占少數)為了圖省事,在強行捕捉異常的壓迫下,選擇捕捉異常的基類型,也就是捕捉所有的異常。這樣當有你無法處理的異常出現時,他們就溺死 在了你的代碼中,而外面的程序全然不知,還在以一種不確定的狀態運行著,這就可能是危險的開始。而如果是 .Net,那么 Unhandled Exception 會被虛擬機捕獲,導致程序異常退出,雖然這從面子上對于用戶不是一個好的交代,但是深層次地他避免了程序在危險的狀態下繼續運行。

          總之,蘿卜白菜各有所愛。我的這篇帖子力求公正地討論了這個問題,希望能對你有所幫助。

    posted on 2007-12-03 10:17 Harriet 閱讀(1067) 評論(1)  編輯  收藏 所屬分類: Java

    FeedBack:
    # re: Java 和 .Net 在異常處理機制上的區別
    2008-07-04 15:17 | 笑笑江南


    能不能把文章簡化成這樣:
    這樣當有你無法處理的異常出現時,他們就溺死 在了你的代碼中,而外面的程序全然不知,還在以一種不確定的狀態運行著,這就可能是危險的開始。而如果是 .Net,那么 Unhandled Exception 會被虛擬機捕獲,導致程序異常退出,雖然這從面子上對于用戶不是一個好的交代,但是深層次地他避免了程序在危險的狀態下繼續運行。   回復  更多評論
      

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


    網站導航:
     

    公 告

    心要沉下去,思緒才會浮上來,水平也就上來了


    <2007年12月>
    2526272829301
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    文章檔案

    相冊

    搜索

    •  

    積分與排名

    • 積分 - 86247
    • 排名 - 669

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲a一级免费视频| 国内精品久久久久久久亚洲| 亚洲自偷自拍另类12p| 国产在线观a免费观看| 狠狠亚洲狠狠欧洲2019| 日本永久免费a∨在线视频| 九月婷婷亚洲综合在线| 丰满妇女做a级毛片免费观看| 亚洲高清视频一视频二视频三| 牛牛在线精品免费视频观看| 亚洲男人的天堂在线va拉文| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 亚洲AV福利天堂一区二区三| 日韩免费无码一区二区三区| 亚洲第一中文字幕| 91久久精品国产免费直播| 亚洲人成网站在线观看播放青青| www.黄色免费网站| 亚洲国产系列一区二区三区| 成人无码区免费视频观看| 亚洲Av永久无码精品一区二区| 国产又大又长又粗又硬的免费视频| 亚洲第一se情网站| 国产亚洲大尺度无码无码专线| 少妇人妻偷人精品免费视频| 亚洲精品视频免费看| 成年人视频在线观看免费| 一级特黄a大片免费| 亚洲国产高清视频| 免费看美女被靠到爽的视频| 免费VA在线观看无码| 亚洲精品成人无码中文毛片不卡| 无码日韩精品一区二区三区免费| 亚洲三级视频在线观看 | 国产成人精品亚洲精品| 免费福利电影在线观看| 亚洲 欧洲 自拍 另类 校园| 亚洲无码视频在线| 国产在线观看片a免费观看 | 亚洲av无码成人精品区一本二本 | 国产成人无码免费网站|