ncyu_phyedu 板


LINE

簡介 所謂例外(Exception),指的是程式發生不正常的錯誤,而導致無法繼續執行的情形。例外 處理(Exception Handling)顧名思義,就是當例外發生時的處理機制。 C語言裡並沒有例外處理的機制,使用函數庫時,可能會發生無法處理的狀況,此時必須由呼 叫者小心檢查傳回值才行。如果不檢查,就會發生無法預期的結果 #include <stdio.h> main() { int data; FILE* f = fopen("sample.txt", "r"); // sample.txt may not exist, fopen returns NULL fscanf(f, "%d", &data); // may result segmentation fault; } 上述例子裡,如果檔案sample.txt不存在,則無法開啟該檔案,因此fopen傳回NULL。如果不 檢查傳回值,則會產生segmentation fault。比較好的寫法是: #include <stdio.h> main() { int data; FILE* f = fopen("sample.txt", "r"); // sample.txt may not exist, fopen returns NULL if (f == NULL) { printf("Can't open file sample.txt. Please check if it exists and you have privilege to access.\n"); return; } fscanf(f, "%d", &data); // may result segmentation fault; } 又例如sqrt()可以用來求平方根,但如果我們給他負數,sqrt該如何處理?根據手冊,sqrt遇 到負數參數,會傳回NaN(Not a Number,是浮點數裡的一個特別數值)。使用sqrt的函數必 須特別檢查該值,否則計算出來的東西都變成了NaN。又例如除法運算時分母是0的情況,嚴 格說起來也是一種錯誤,某些系統也會產生floating exception (core dumped)。 沒有提供例外處理機制的語言,程式的正確性必須靠極端小心的設計者才行。為了減少程 式錯誤的機會,讓軟體很強固(robust),Java提供了例外處理的機制。 相關語法 在Java裡,Exception是一個Class。Exception extends Throwable, Throwable extends Object。Exception,Throwable這兩個類別均定義於java.lang這個package內。設計者也 可以自訂自己的Exception類別。相關的Exception語法如下: 自訂Exception類別 public class MyException extends Exception { } 宣告某method會產生例外 import java.io.*; public class ExceptionExample { public void someMethod() throws Exception { // 請注意throws最後面是s // some code may fail FileInputStream f; try { f = new FileInputStream("abc.txt"); // if abc.txt does not exist, FileNotFoundException will be caught } catch(FileNotFoundException fnf) { System.out.println("File not found. Generate an exception and throw it"); throw fnf; // 注意throw後面沒有s // throw new Exception(); // or you can throw a new Exception object } } public static void main(String[] argv) { ExceptionExample s = new ExceptionExample(); try { s.someMethod(); } catch(Exception epp) { System.out.println("An Exception has been caught."); } } } 攔截exception的語法 try { } catch (TypeOneException e1) { } catch (TypeTwoException e2) { } catch (TypeThreeException e3) { } finally { } try {} catch{}類似像if then else if的結構。當try {}裡面某一行指令產生Exception 時,try區塊會立刻中斷執行,然後到第一個catch判斷抓到的Exception是否instanceof TypeOneException,如果是則執行該catch區塊;如果不是,則進一步比較instanceof TypeTwoException。也就是說雖然可以寫很多個catch區塊,但執行時最多只有一塊會執行 到。離開try或catch區塊以前,如果有finally區塊,則finally區塊一定會被執行到。一般 來說finally區塊裡面的程式碼大多用來作資源回收,或清理資料結構的工作,以確保不論 有無發生狀況,程式都能繼續正常執行。 try { System.out.println("Opening FileInputStream"); FileInputStream f = new FileInputStream("abc.txt"); // assume this operation generate FileNotFoundException System.out.println("File Opened"); } catch (FileNotFoundException e1) { System.out.println("FileNotFoundException caught"); } catch (Exception e2) { System.out.println("Exception caught"); } finally { System.out.println("Execute finally block"); } 上述的範例會印出 Opening FileInputStream FileNotFoundException caught Execute finally block 如果把上面例子稍微改一下: try { System.out.println("Opening FileInputStream"); FileInputStream f = new FileInputStream("abc.txt"); // assume this operation generate FileNotFoundException System.out.println("File Opened"); } catch (Exception e2) { System.out.println("Exception caught"); } catch (FileNotFoundException e1) { System.out.println("FileNotFoundException caught"); } finally { System.out.println("Execute finally block"); } 則聰明一點的Compiler會抱怨FileNotFoundException的區塊unreachable(執行不到)。這 是因為FileNotFoundException是Exception的子類別,因此如果產生的例外是instanceof Exception,則FileNotFoundException就不會執行了;若產生的例外不是instanceof Exception,那就更不會執行到FileNotFoundException區塊了。 是否所有的Exception都要處理? 原則上是的。只要用到的method有宣告throws SomeException,則呼叫該method的地方,就 要使用try {} catch(SomeException)的語法。當然像是try {} catch(SuperClassOfSomeException)的用法也行。唯一的例外是 java.lang.RuntimeException及其子類別可以不必處理。 哪些屬於RuntimeException呢?像是ArrayIndexOutOfBoundException就是其中之一,它發 生在陣列索引不合法的情況下: public class Test { public static void main(String[] argv) { int[] x = new int[10]; x[100] = 0; // will generate ArrayIndexOutOfBoundException } } exception產生時,JVM會由堆疊追蹤此錯誤點的呼叫資訊,並一一向外檢查,直到有try catch區塊攔截此exception為止。在上述的例子中,沒有任何try catch的宣告,則JVM會終 止該執行緒。 類別Exception的相關方法 抓到例外後,可透過該例外物件,得到有趣的資訊 toString()以簡單的字串描述該例外 getMessage()列出細節訊息 printStackTrace()將堆疊資訊印在螢幕上,可幫助設計者快速找到錯誤點 Error 前面提到Exception是Throwable的子類別。另一個Throwable的子類別是java.lang.Error 。所謂Error指的是嚴重的錯誤情況。當Error產生時,其行為和Exceptio類似,但是try catch區塊沒有辦法攔下它們,最後會由JVM來處理Error,並中斷執行緒的執行。像 OutOfMemoryError,StackOverflowError都是Error的子類別。 範例 用Link List實作Stack public class Stack { private Node head; private int size; class Node { Object data; Node next; } public void push(Object s) { Node tmp = new Node(); tmp.next = head; tmp.data = s; size++; head = tmp; } public Object pop() throws Exception { if (head == null) { throw new Exception(); } Object tmp = head.data; head = head.next; size--; return tmp; } } public class Example { public static void main(String[] argv) { Stack s1 = new Stack(); Stack s2 = new Stack(); s1.push("abc"); s1.push("def"); s2.push("123"); s2.push("456"); try { s1.pop(); } catch(Exception e) {} } } public class Example2 { public static void main(String[] argv) throws Exception { Stack s1 = new Stack(); Stack s2 = new Stack(); s1.push("abc"); s1.push("def"); s2.push("123"); s2.push("456"); s1.pop(); } } 用Link List實作Queue public class Queue { private Node head, tail; private int size; class Node { Object data; Node next; } public void put(Object s) { Node tmp = new Node(); tmp.data = s; if (tail != null) { tail.next = tmp; } else { head = tmp; } tail = tmp; size++; } public Object get() throws Exception { if (head == null) { throw new Exception(); } Object tmp = head.data; head = head.next; if (head == null) { tail = null; } size--; return tmp; } } --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.58.22.74







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP