<ccid_nobr></ccid_nobr>
<ccid_code><font color="#a52a2a">FILE *fp; fp=fopen(filename,"rw"); if(fp==NULL){ printf("cannot open file/n"); exit(0); }</font></ccid_code> |
在這段程åºä¸ï¼Œifæ¢ä»¶èªžå¥ä¸çš„一段用來處ç†æ²’æœ‰æ‰¾åˆ°æŒ‡å®šæ–‡ä»¶ï¼Œæˆ–è€…å…¶å®ƒåŽŸå› ç„¡æ³•æ£ç¢ºæ‰“開指定文件。å¯æ˜¯å¦‚æžœé‡åˆ°ä¸€å€‹è²¬ä»»å¿ƒä¸å¼·çš„程åºå“¡ï¼Œä»–å¯èƒ½èªç‚ºå‡ºç¾(xià n)找ä¸åˆ°æ–‡ä»¶çš„å¯èƒ½æ€§å¾ˆå°ï¼Œæˆ–者由于æ€è·¯é›†ä¸åœ¨ç¨‹åºåŠŸèƒ½çš„實ç¾(xià n)上而忘記了處ç†é€™ç¨®æƒ…æ³ã€‚這時程åºåŒæ¨£å¯ä»¥æ£ç¢ºç·¨è¯ï¼Œè€Œä¸”一般情æ³ä¸‹ä¹Ÿä¸æœƒå‡ºç¾(xià n)å•é¡Œã€‚但æ¤æ™‚這段程åºå¯ä»¥è‚¯å®šèªªæ˜¯ä¸å¤ å¥å£¯çš„,而且一旦這段程åºç™¼(fÄ)生了錯誤也會讓程åºå“¡å¾ˆé›£ç™¼(fÄ)ç¾(xià n)錯誤出在哪里。在C語言以åŠå…¶å®ƒå¤§å¤šæ•¸(shù)高級語言ä¸éƒ½å¯ä»¥èˆ‰å‡ºå¾ˆå¤šé€™ç¨®ä¾‹å。
也就是一個函數(shù)在使用的時候,å¯èƒ½æœƒå‡ºç¾(xià n)并沒有é”到這個函數(shù)的使用目的的情æ³ï¼Œå“ªæ€•åœ¨é€™æ®µç¨‹åºçš„特定使用環(huán)境下發(fÄ)生這種異常情æ³çš„å¯èƒ½æ€§åªæœ‰è¬åˆ†ä¹‹ä¸€ã€‚常用處ç†çš„方法就是,程åºå“¡åœ¨éœ€è¦ä½¿ç”¨æŸå€‹å‡½æ•¸(shù)æ™‚å¿…é ˆå……åˆ†äº†è§£å¯èƒ½æœƒæœ‰ä»€ä¹ˆåŽŸå› ?qÅ«)е略摵瘮?shù)ä¸èƒ½æ£ç¢ºåŸ·(zhÃ)行,然åŽåŠ 入相應的æ¢ä»¶åˆ¤æ–·èªžå¥ä¾†é€²è¡Œè™•ç†ã€‚åŽé¢å°‡æœ‰ä¸€å€‹ä¾‹å說明這個å•é¡Œã€‚
而Javaçš„"異常機制"就是在處ç†ä¸Šè¿°å•é¡Œä¸çµ¦äº†ç¨‹åºå“¡éžå¸¸ç°¡å–®è€Œéˆæ´»çš„æ–¹å¼ã€‚一般來說,其它高級語言主è¦æ˜¯è®“函數(shù)使用者來關注該函數(shù)å¯èƒ½æœƒå‡ºç¾(xià n)的異常情æ³ï¼Œè€Œjava則是把這件事情交給方法(和函數(shù)å°æ‡‰çš„概念,在Javaä¸ç¨±æ–¹æ³•)çš„è¨è¨ˆè€…來åšã€‚這å°äºŽæ–¹æ³•çš„使用者來說帶來的方便是ä¸æœƒå› 為責任心ä¸å¼·ï¼Œæˆ–者辦事丟三那四,會忘了在使用方法時處ç†å¯èƒ½ç™¼(fÄ)生的異常情æ³ã€‚而麻煩就是,在使用一個å¯èƒ½æœƒç™¼(fÄ)生異常的方法時,絕å°ä¸èƒ½è¦–而ä¸è¦‹ï¼Œè€Œå¿…é ˆåšå‡ºç›¸æ‡‰çš„處ç†ã€‚也就是說象上述C程åºæ®µä¸ï¼Œå¦‚果忘了if程åºå¡Šï¼Œé€™å€‹ç¨‹åºç”šè‡³é‚„能蒙éŽä¸€å€‹å¤–行上å¸ï¼Œä½†ç•¶ä½¿ç”¨Java來完æˆé€™å€‹åŠŸèƒ½æ™‚,åªè¦ç”¨åˆ°çš„方法使用了"異常"機制,如果ä¸å°å¯èƒ½ç”¢(chÇŽn)生"異常"的方法進行相應處ç†ï¼Œjavaç·¨è¯å™¨æ˜¯ä¸æœƒè®“其通éŽçš„。
一ã€"異常類"的組織形å¼
Java系統(tÇ’ng)é¡žä¸çš„方法產(chÇŽn)生的異常都被組織æˆ"異常類"(還有Error類,ä¸åœ¨æœ¬æ–‡è¨Žè«–范åœï¼‰ï¼Œæ¤æ–¹æ³•å’Œå®ƒç›¸é—œçš„"異常類"通éŽthrowsé—œéµå—é—œè¯(lián)åœ¨ä¸€èµ·ï¼Œå¹¶ä¸”é€™äº›é¡žéƒ½å¿…é ˆæ˜¯Exceptioné¡žçš„å類。任何一個自己開發(fÄ)的類的方法ä¸å¦‚æžœå¯èƒ½æœƒç”¢(chÇŽn)生æŸç¨®ç•°å¸¸ï¼Œä¹Ÿå¯ä»¥å°‡é€™ç¨®ç•°å¸¸çµ„ç¹”æˆä¸€å€‹"異常類",但這個"異常類"åŒæ¨£å¿…é ˆæ˜¯Exceptionçš„å類,或?qÅ«)Oåé¡žç‰ç‰ã€‚
例1:
<ccid_nobr></ccid_nobr>
<ccid_code><font color="#a52a2a">/*isLegal于檢查數(shù)æ“š(jù)是å¦åˆæ³•ï¼Œç•¶>0時視為åˆæ³•ï¼Œè¿”回åˆæ³•å€¼ï¼Œ *å¦å‰‡è¦–為ä¸åˆæ³•ï¼Œæ‹‹å‡º"異常"。*/ int isLegal(int dt) throws LowZeroException//這種定義本文ä¸å‡ç¨±ç‚ºæ–¹æ³•èˆ‡"異常"通 {                  //éŽthrows建立了關è¯(lián) if(dt>=0){ return data; } else throw new LowZeroException(); } /*自已寫的異常類,繼承自Exception*/ class LowZeroException extends Exception { public LowZeroException(){ super(); } }</font></ccid_code> |
仔細觀察方法isLegal(),它體ç¾(xià n)出的最值得注æ„的特色是,它有兩種方å¼çš„函數(shù)出å£ï¼Œä¸€ç¨®æ˜¯é€šéŽreturn語å¥ï¼Œè¿”回的是方法本身定義的類型的實例,å¦ä¸€ç¨®æ˜¯é€šéŽthrow,返回的是"異常類"çš„å°è±¡å¯¦ä¾‹ï¼ŒJavaä¸ç¨±ä¹‹ç‚ºæ‹‹å‡º"異常"。å°æ¯”一下Cä¸å¦‚何處ç†åŒæ¨£çš„å•é¡Œçš„:
<ccid_nobr></ccid_nobr>
<ccid_code><font color="#a52a2a">int isLegal(int dt) { if(dt>=0){ return data; } else return -1;//通éŽä¸€å€‹ç‰¹å®šå€¼ä¾†è¡¨æ˜Žå‡ºéŒ¯ }</font></ccid_code> |
由于Cåªèƒ½é€šéŽreturn返回函數(shù)值,所以在處ç†ç•°å¸¸æƒ…æ³æ™‚則å¯èƒ½é€šéŽä»¥ä¸Šæ–¹å¼ä¾†è™•ç†ã€‚當然這就è¦æ±‚isLegal()函數(shù)çš„ä½¿ç”¨è€…å¿…é ˆçŸ¥é“函數(shù)ä¸ä½¿ç”¨è¿”回值-1來表明出ç¾(xià n)ä¸åˆæ³•æ•¸(shù)æ“š(jù)的情æ³ã€‚
å°æ¯”這兩種處ç†æ–¹æ³•ï¼Œå¯ä»¥çŸ¥é“javaçš„"異常機制"把處ç†ç•°å¸¸äº‹ä»¶çš„è·èƒ½å’Œæ–¹æ³•æœ¬èº«çš„è·èƒ½é€šéŽå…©å€‹ä¸åŒå‡ºå£åˆ†é›¢é–‹ä¾†ã€‚
所有這些"異常類"ç¨ç«‹äºŽå®ƒå…·é«”æœå‹™çš„方法被統(tÇ’ng)一組織æˆä¸€å€‹é¡žæ¨¹ã€‚"異常機制"å°±å¥½æ¯”é«˜æ ¡çš„åŽå‹¤ç¤¾æœƒåŒ–一樣,通éŽåŽå‹¤ç¤¾æœƒåŒ–å°‡å¸æ ¡çš„æ•™å¸è·èƒ½å’Œå¸æ ¡çš„åŽå‹¤ä¿éšœåˆ†é›¢é–‹ä¾†ï¼Œå¹¶ä¸”åŽå‹¤é›†åœ˜çš„組織形å¼ä¹Ÿæ˜¯ç¨ç«‹äºŽå¸æ ¡ä¸»é«”的。事實è‰æ˜Žï¼Œé€™ç¨®çµ„織方å¼ä¸åƒ…æ高了æœå‹™æ•ˆçŽ‡ï¼Œä¹Ÿæ高了æœå‹™è³ª(zhì)é‡ã€‚整個Java體系ä¸çš„"異常類"組織形å¼å¦‚圖1所示:
在例1ä¸çš„isLegal()方法如果在調(dià o)用éŽç¨‹ä¸æ²’有能æ£å¸¸è¿”回整形數(shù),而是在"異常"產(chÇŽn)生點產(chÇŽn)生了"異常"å°è±¡ï¼Œé‚£ä¹ˆé€™å€‹"異常"å°è±¡ç”±èª°ä¾†æŽ¥æ”¶ï¼Œå¹¶è™•ç†å®ƒå‘¢ï¼Ÿä»¥ä¸‹å°±ä¾†è§£ç”這個å•é¡Œã€‚
二ã€"異常"的處ç†éŽç¨‹
Javaä¸ç”±try…catch語法來處ç†"異常",將關è¯(lián)有"異常類"的方法包å«åœ¨try{}程åºå¡Šä¸ï¼Œcatch(){}é—œéµå—å¯ä»¥ä½¿ç”¨å½¢åƒï¼Œç”¨äºŽå’Œæ–¹æ³•ç”¢(chÇŽn)生的"異常"å°è±¡çµåˆã€‚當調(dià o)用æŸå€‹æ–¹æ³•æ™‚,引起異常事件發(fÄ)生的æ¢ä»¶æˆç«‹ï¼Œä¾¿æœƒæ‹‹å‡º"異常",原來的程åºæµç¨‹å°‡æœƒåœ¨æ¤æ–¹æ³•è™•ä¸æ–·ï¼Œç„¶åŽtry模塊åŽç·Šè·Ÿçš„catchä¸çš„"å½¢åƒ"å’Œæ¤ç•°å¸¸å°è±¡å®Œæˆäº†çµåˆï¼Œç¹¼è€Œé€²å…¥äº†catch模塊ä¸é‹è¡Œã€‚å…·é«”éŽç¨‹èˆ‰ä¾‹èªªæ˜Žï¼š
例2:
<ccid_nobr></ccid_nobr>
<ccid_code><font color="#a52a2a">/*將關è¯(lián)有異常的方法包å«åœ¨try模塊ä¸*/ int myMethod(int dt){ int data = 0; try{ int data = isLegal(dt); }catch(LowZeroException e){ System.out.println("發(fÄ)生數(shù)æ“š(jù)錯誤ï¼"); } return data; }</font></ccid_code> |
三ã€"異常"的處ç†æ–¹æ³•
有兩種方法處ç†"異常":第一種如例2,將å«æœ‰"異常"出å£çš„方法直接放到tryå¡Šä¸ï¼Œç„¶åŽç”±ç·Šéš¨å…¶åŽçš„catchå¡Šæ•æ‰ã€‚第二種是ä¸ç›´æŽ¥ç›£(jiÄn)è½æ•æ‰è¢«å¼•ç”¨æ–¹æ³•çš„"異常",而是將這個"異常"é—œè¯(lián)傳éžçµ¦å¼•ç”¨æ–¹æ³•ï¼ŒåŒæ™‚監(jiÄn)è½æ•æ‰å·¥ä½œä¹Ÿç›¸æ‡‰å‘上傳éžã€‚
例3:
<ccid_nobr></ccid_nobr>
<ccid_code><font color="#a52a2a">int myMethod2(int dt) { int data = 0; try{ data = myMethod(dt) }catch(LowZeroException e){ System.out.println("發(fÄ)生數(shù)æ“š(jù)錯誤ï¼"); e.printStackTrace(); } return data; } int myMethod(int dt) throws LowZeroException { int data = isLegal(dt); //æ¤è™•å¼•ç”¨isLegal()方法,但并沒有æ•æ‰å®ƒçš„"異常" return data; }</font></ccid_code> |
從上例ä¸å¯ä»¥çœ‹åˆ°æ–¹æ³•myMethod()與它引用的方法isLegal()產(chÇŽn)生的"異常"LowZeroException建立了關è¯(lián),也就是完æˆäº†å°‡"異常"é—œè¯(lián)çš„å‘上傳éžï¼Œæ¤æ™‚çš„myMethod()方法體ä¸é›–然åªæœ‰ä¸€å€‹return返回語å¥ï¼Œä½†å®ƒäº‹å¯¦ä¸ŠåŒæ¨£æœ‰å…©ç¨®æ–¹å¼çš„函數(shù)出å£ï¼Œä¸€ç¨®æ˜¯ç”±return返回的整形值,å¦ä¸€ç¨®å‰‡æ˜¯è¿”回方法åä¸çš„throwsé—œéµå—所指的"異常類"的實例å°è±¡ã€‚相應的,監(jiÄn)è½æ•æ‰çš„工作交給了上一層方法myMethod2()。åŒæ¨£çš„é“ç†ï¼ŒmyMethod2()也å¯ä»¥å°‡"異常"通éŽthrowsçš„é—œè¯(lián)繼續(xù)å‘上傳éžã€‚這樣的話,一旦一個"異常"被æ•æ‰åˆ°æ™‚,這個"異常"必有一個傳éžè·¯å¾‘,而如果我們在æ•æ‰é»žçš„catch程åºå¡Šä¸åŠ å…¥printStackTrace()方法,便能清楚的看到這個"異常"是怎樣傳éžéŽä¾†çš„。例如在例3如果有"異常"被æ•æ‰åˆ°ï¼Œe.printStackTrace()打å°å‡ºä¾†çš„çµæžœå°‡æ˜¯ï¼š
LowZeroException:
at Example.isLegal
at Example myMethod
at Example.myMethod2
at Example main
從上çµæžœä¸æˆ‘們å¯ä»¥çœ‹åˆ°ï¼Œå¾žLowZeroException"異常"產(chÇŽn)生點,å³åŒ…å«throw new LowZeroException();åå¥çš„方法開始,然åŽä¸€ç›´è¿½æº¯åˆ°ç”¢(chÇŽn)生當å‰ç·šç¨‹çš„方法(注æ„:printStackTrace()并ä¸æ˜¯è¿½æº¯åˆ°æ•æ‰é»žçµæŸï¼Œè€Œæ˜¯åˆ°ç”¢(chÇŽn)生當å‰ç·šç¨‹çš„方法çµæŸï¼‰ã€‚"異常"產(chÇŽn)生點產(chÇŽn)生的LowZeroException"異常"å°è±¡ï¼Œé¦–先被賦給了isLegal()é—œè¯(lián)çš„LowZeroExceptioné¡žçš„ç„¡å引用,然åŽç¹¼çºŒ(xù)賦給myMethod()é—œè¯(lián)çš„LowZeroExceptioné¡žçš„ç„¡å引用,å†ç¹¼çºŒ(xù)賦給myMethod2()ä¸çš„catchå¡Šä¸çš„å½¢åƒe,最åŽåœ¨é€™é‡Œè¢«è™•ç†æŽ‰ï¼Œé€™å€‹"異常"å°è±¡éš¨å³æ¶ˆå¤±??梢哉f,catch(){}就是"異常"å°è±¡çš„生命終çµé»žã€‚
å¦å¤–é‚„è¦æ³¨æ„一點,方法與"異常"çš„é—œè¯(lián)å¯ä»¥ä¸€ç›´å‘上傳éžï¼Œç•¶å‚³éžåˆ°èˆ‡main方法關è¯(lián)åŽï¼Œå³åœ¨main()方法的定義ä¸ä½¿ç”¨äº†throws Exceptionï¼Œé€™æ™‚é™¤äº†è™›æ“¬æ©Ÿæ²’æœ‰å…¶å®ƒæ–¹æ³•èƒ½å¤ å¼•ç”¨main()方法,且在程åºä¸å¯èƒ½çœ‹ä¸åˆ°try…catch程åºå¡Šï¼Œä½†å¹¶ä¸æœƒç”¢(chÇŽn)ç”ŸéŒ¯èª¤ï¼Œå› ç‚ºæ¤æ™‚虛擬機會æ•æ‰"異常",并且會默èªçš„調(dià o)用printStackTrace()方法打å°å‡º"異常"路徑。總之åªè¦ä¸€å€‹æ–¹æ³•é—œè¯(lián)了"異常",å¯ä»¥å°‡é€™å€‹"異常"é—œè¯(lián)å‘上傳éžï¼Œä½†æ˜¯æœ€çµ‚å¿…é ˆä½¿ç”¨catch來終æ¢"異常",或者一直傳éžåˆ°main()方法交給Java虛擬機來çµæŸ"異常"å°è±¡çš„生命,å¦å‰‡æ˜¯é€šä¸éŽç·¨è¯çš„。
å››ã€ä½¿ç”¨"異常機制"的需è¦æ³¨æ„的幾點
1.一個方法ä¸å¯èƒ½æœƒç”¢(chÇŽn)生多種ä¸åŒçš„ç•°å¸¸ï¼Œä½ å¯ä»¥è¨ç½®å¤šå€‹"異常"拋出點來解決這個å•é¡Œã€‚
2."異常"å°è±¡å¾žç”¢(chÇŽn)生點產(chÇŽn)生åŽï¼Œåˆ°è¢«æ•æ‰åŽçµ‚æ¢ç”Ÿå‘½çš„å…¨éŽç¨‹ä¸ï¼Œå¯¦éš›ä¸Šæ˜¯ä¸€å€‹å‚³å€¼éŽç¨‹ï¼Œæ‰€ä»¥ä½ å¯ä»¥æ ¹æ“š(jù)需è¦ï¼Œä¾†åˆç†çš„控制檢測到"異常"的粒度。例如在例3ä¸ï¼Œå¦‚æžœä½ å¹¶ä¸éœ€è¦çŸ¥é“具體產(chÇŽn)生的是LowZeroException"異常"ï¼Œé‚£ä¹ˆä½ å¯ä»¥ä½¿ç”¨"異常"的公共父類Exception來çµåˆ"異常"å°è±¡ï¼Œå³catch(Exception e){…}。åŒæ¨£åœ¨"異常"與方法關è¯(lián)的傳éžéŽç¨‹ä¸ï¼Œä¹Ÿå¯ä»¥æ ¹æ“š(jù)需è¦æŽ§åˆ¶é—œè¯(lián)"異常"的粒度,å³throwsåŽé¢è·Ÿä¸Šç•°å¸¸å°è±¡çš„父類å。
3."異常機制"ä¸é‚„有一種特殊情æ³â€•â€•RuntimeException"異常類"(見圖1),這個"異常類"和它的所有å類都有一個特性,就是"異常"å°è±¡ä¸€ç”¢(chÇŽn)生就被Java虛擬機直接處ç†æŽ‰ï¼Œå³åœ¨æ–¹æ³•ä¸å‡ºç¾(xià n)throw åå¥çš„地方便被虛擬機æ•æ‰äº†ã€‚å› æ¤å‡¡æ˜¯æ‹‹å‡ºé€™ç¨®"é‹è¡Œæ™‚異常"的方法在被引用時,ä¸éœ€è¦æœ‰try…catch語å¥ä¾†è™•ç†"異常"。
æ›´å¤šæ–‡ç« ã€æŠ€è¡“交æµã€å•†å‹™åˆä½œã€è¯(lián)ç³»åšä¸»
微信掃碼或æœç´¢ï¼šz360901061

å¾®ä¿¡æŽƒä¸€æŽƒåŠ æˆ‘ç‚ºå¥½å‹
QQ號è¯(lián)系: 360901061
您的支æŒæ˜¯åšä¸»å¯«ä½œæœ€å¤§çš„動力,如果您喜æ¡æˆ‘çš„æ–‡ç« ï¼Œæ„Ÿè¦ºæˆ‘çš„æ–‡ç« å°æ‚¨æœ‰å¹«åŠ©ï¼Œè«‹ç”¨å¾®ä¿¡æŽƒæ下é¢äºŒç¶ç¢¼æ”¯æŒåšä¸»2å…ƒã€5å…ƒã€10å…ƒã€20å…ƒç‰æ‚¨æƒ³æ的金é¡å§ï¼Œç‹ ç‹ é»žæ“Šä¸‹é¢çµ¦é»žæ”¯æŒå§ï¼Œç«™é•·éžå¸¸æ„Ÿæ¿€æ‚¨ï¼æ‰‹æ©Ÿå¾®ä¿¡é•·æŒ‰ä¸èƒ½æ”¯ä»˜è§£æ±ºè¾¦æ³•ï¼šè«‹å°‡å¾®ä¿¡æ”¯ä»˜äºŒç¶ç¢¼ä¿å˜åˆ°ç›¸å†Šï¼Œåˆ‡æ›åˆ°å¾®ä¿¡ï¼Œç„¶åŽé»žæ“Šå¾®ä¿¡å³ä¸Šè§’掃一掃功能,é¸æ“‡æ”¯ä»˜äºŒç¶ç¢¼å®Œæˆæ”¯ä»˜ã€‚
ã€æœ¬æ–‡å°æ‚¨æœ‰å¹«åŠ©å°±å¥½ã€‘å…ƒ
