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

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

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

    我對Java的異常處理機制的理解

    Posted on 2006-09-14 16:40 英雄 閱讀(1437) 評論(1)  編輯  收藏

    我對Java的異常處理機制的理解

    ?? 首先從一個問題引出一個角度:跑java程序的機器在如何運行?

    ?? Jvm 和物理機器構成了一個運行環境。這個運行環境“吸收”提供的class文件或其他資源,包括java main入口的給定參數等等,以多線程thread形式運行著。線程在另一個線程中誕生出來,某一天魂歸西天。在線程誕生之初就屬于一個分組threadgroup

    ?? 然后描述另外一個角度:所謂運行環境吸收的材料中,比如class文件,其實是我們程序員給的運行規定。就是說我們按java language specification給出了我們對如何運行的命令信息。實際運行和我們的意愿之間到底是怎么相關呢?

    運行環境的出現之初就會按我們的意愿試圖執行某個類的main.首先運行環境會誕生一個主線程,這個主線程首先要求運行環境已經initializing這個類,沒有就得initializing這個類,在做initializing之前又得要求linking,以致loading,不管怎么樣,這樣的約定導致主線程會運行loadinglinking,initializing,然后再運行main方法里我們表達的意思。當然在這個主線程里也會按我們的意思誕生新線程,這個新線程也還是得在誕生之初按我們的意愿試圖執行那個runable類的run方法,這當然也得要求initializing。所不同的是有可能這個initializing在某個其他線程里給運行了,那么也就是說運行時環境滿足了這個要求,那在當前線程中就不干這個事了。

    ?? 最后我們來看異常的概念。

    ?? 顯然我們的意愿是不容違背的。呵呵。可是現實歸現實,總有那么多不盡人意。當運行時環境參照我們的意愿以各個線程運行時,總可能出現點違背意愿的事,也就是異常。這個情況的出現可能是機器內存條抖了下,可能是我們的意愿就不正常,比如想數組越界訪問,或者我們的意愿就是“請此刻馬上當作異常發生了”等等。那么這時會怎么運行呢?

    ?? 這種情況當然是在線程中發生的,發生后運行時大師就會根據當前情況構造一throwable實例,然后尋找本線程要轉到哪個點上去繼續運行。這到底是哪個點,這個意愿當然還得我們程序員通過java language specification給出命令信息。我們的意愿不一定非要寫出來,有一個是約定好的:異常傳播跳出前釋放同步塊的鎖。那么如果運行時大師找到了這個點,就會安排本線程繼續從這個點運行,找不到,那么運行時大師就會把該線程殺了。殺之前先執行它的threadgroupuncaughtException方法里我們表達的意愿。注意不管是在那個點還是這個方法,我們都有機會表達對那個throwable實例怎么怎么樣的想法。

    ?? Ok, 現在基本框架已經有了,再具體的描述下。

    ?? 剛才說到了每個線程的運行,異常是有很多種情況的。那這種情況算什么時候發生的呢?總起來說就是什么時候觸發了執行,什么時候算。比如我們有一句a=1/b.當線程參照這句執行時,發現b=0,那就可以說在這時發生了個異常。再比如我們某StringUtils.contact(s1,s2);當線程參照這句執行時,可能就會要求先做StringUtilsresolvinglinking的最后一個可選步驟),但也可能在線程link該句所屬的類時就會做,這根據jvm規范得看jvm怎么實現了。但不管怎么說,什么時候做的resolving,而在這個過程中出異常了,就得算這個點。這樣就有一個意識:發生點是可以嵌套的。比如a方法a步調用b方法,但bb步拋異常了,我們可以說b步是個點,但對a來說,a步也是這個點。最原始的那個點怎么算?怎么說都無所謂。但有謂的是下面:

    ?? 運行時大師就會根據當前情況構造一個throwable實例!其中當前情況就有一個當前線程的執行棧信息。這個當前信息怎么算有所謂。而且,然后尋找線程要轉到哪個點上去繼續運行。從哪里開始找起也有所謂。這兩個所謂都在jvm中規范了。

    ?? 關鍵是我們程序員如何表達。

    • ?? 1 當前信息就是線程當時的棧信息。注意這個棧信息是我們的程序(包括Lib)的某個方法名的一些信息,而不是細化到某個操作2進制指令。

    • ?? 2 從哪里找起?

    ?? 我們的程序中哪句是最終導致異常的,從這一句所在的代碼塊開始找起。所以主線程一開始時initialize那個main類,如果jvm實現是最早link,那么可能會由此遞歸initialize很多main類應用的類,如果這個過程中出異常了,我們甚至就沒有必要找了,之后怎么處理無所謂;如果initialize后執行main方法過程中某句導致出異常了,那就得從這一句所在的代碼塊開始找起。Try{ ~~~;a;~~~;}catch{}finally{} Catch不匹配就要跳出這個try塊,但跳出之前也要先讓本線程運行完finally。如果catch,finally又拋異常了,那就形成一個新異常,原來的異常的信息不見了,所以要小心。注意“那個最終導致異常的那一句”是這個意思,比如Try{~~~;a();~~~;}catch{}finally{}a()出異常了,但不是a()句,而是a()方法中出異常的最終那一句,由此遞歸到程序可見的最終一句。從那個地方找起。

    異常多數是同步發生的,就是在線程的某個固定環節發生,但也有異步的,比如內存溢出,誰也不知道會在哪個線程中哪個點發生,對于這樣的異步異常,jvm規范中說jvm實現讓這種異常實際發生后代碼繼續運行一有限段,所以給出一個簡單實現模型:運行時對這種異常的檢測時每次線程做控制轉移指令時,比如條件轉移啊等等。

    ?? 但是無論什么異常,對于我們用java表達的意愿,必須滿足:異常邏輯發生時之前的java都執行了,之后的都沒有執行。至于實際實現中,可能我們看到的異常發生時刻和實際的發生時刻有差別(因為運行時檢測不是實時的),也可能我們看到的代碼執行和編譯器優化后實際的執行順序不一致,但不管怎么樣,我們看到的和表達的必須一致。

    ?? 最后看異常的分類。我截至目前說的異常都是一個廣義的概念,實際上應該對應throwable這個類。Throwable之下有exceptionerror.exception下有很多,其中有一個是RuntimeException。我們用他們表達對運行的意愿,同時我們也用他們表達我們對提供的接口運行時可能出現的異常的提示。這種表達是java的特色,一般語言不會直接表達這種可能性。假如說我們的某個方法可能拋exception,意思是別人使用這個方法時能處理這個異常,對非runtimeexception一定要么捕捉下,要么繼續傳播;對runtimeexception,可以不做處理。而假如說我們的某個方法可能拋error,意思則是別人用這個方法可能會面對error,而且不認為別人能處理。從另一個方面,對于我們使用某個方法,如果他聲明會拋一個非runtimeexception,我們必須處理,真有error的可能我們都不用,當然也可能記下日志就算了。考慮到這種含義,編譯器幫助我們一定要處理非runtimeexception

    Feedback

    # re: 我對Java的異常處理機制的理解   回復  更多評論   

    2006-09-14 22:00 by stoneshao
    今天設計一塊功能代碼的異常,打開firefox就看到了這篇文章,呵呵。
    也怪了,最近開發涉及什么總能及時在blogjava上看到相關的文章,;)

    寫的比較天馬行空,隨意了一點,但還是有點收獲:D

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


    網站導航:
     
    主站蜘蛛池模板: 中文字幕人成人乱码亚洲电影| 毛片免费全部免费观看| 国产亚洲精品AA片在线观看不加载| 亚洲精品无码高潮喷水A片软| 日本一区二区三区免费高清| 亚洲av永久综合在线观看尤物| 黄色免费网站网址| 亚洲五月丁香综合视频| 成年私人影院免费视频网站| 亚洲av永久中文无码精品综合| 国产高清免费在线| 一级毛片不卡免费看老司机| 亚洲日本中文字幕天堂网| 国产精品无码永久免费888| 亚洲色WWW成人永久网址| 日本免费人成视频在线观看| 亚洲三级在线视频| 日韩亚洲国产二区| 久操视频免费观看| 亚洲乱码在线观看| 亚洲精品视频免费| 污污网站免费观看| 亚洲人成网站在线在线观看| 国产一级理论免费版| 91福利免费网站在线观看| 亚洲成年轻人电影网站www| 18禁免费无码无遮挡不卡网站 | 欧亚一级毛片免费看| 日韩一卡2卡3卡4卡新区亚洲| 老汉精品免费AV在线播放| 国产亚洲sss在线播放| 四虎亚洲国产成人久久精品| 久久一本岛在免费线观看2020| 亚洲已满18点击进入在线观看| 亚洲国产综合无码一区二区二三区| 国产精品免费观看调教网| 亚洲码和欧洲码一码二码三码 | 亚洲日本一区二区一本一道| 足恋玩丝袜脚视频免费网站| 日韩在线视精品在亚洲| 亚洲日本一区二区|