Posted on 2010-04-15 23:11
帥子 閱讀(2632)
評論(0) 編輯 收藏 所屬分類:
j2se技術專區 、
申請加入java團隊
1.前言:
你的程序總有一天會崩潰掉,在崩潰掉的時候我們要知道它在哪,為了什么而崩潰掉,數據的保存或者丟失情況如何等問題。我們可以通過繼承類java.lang.Throwable的子類:Exception來設計我們自己的Java異常。Exception類用于描述程序能夠捕獲的異常,如ClassNotFoundException。要注意的是自定義異常類之間也可以有繼承關系,同時也需要為自定義異常類設計構造方法,以方便構造自定義異常對象。
2.設計實例分析:
這是個比較完整的自定義異常類的設計,其實是比較模板化的東西。
package?playground; import?java.io.*; public?class?MyException?extends?Exception?{ private?int?id;?//?a?unique?id private?String?classname;?//?the?name?of?the?class private?String?method;?//?the?name?of?the?method private?String?message;?//?a?detailed?message private?MyException?previous?= null;?//?the?exception?which?was?caught private?String?separator?=?"\n";?//?line?separator public?MyException(int?id,?String?classname,?String?method, String?message,?MyException?previous)?{ this.id?=?id; this.classname?=?classname; this.method?=?method; this.message?=?message; this.previous?=?previous; } public?String?traceBack()?{ return?traceBack("\n"); } public?String?traceBack(String?sep)?{ this.separator?=?sep; int?level?=?0; MyException?e?=?this; String?text?=?line("Calling?sequence?(top?to?bottom)"); while?(e?!=?null)?{ level++; text?+=?line("--level?"?+?level?+?"--------------------------------------"); text?+=?line("Class/Method:?"?+?e.classname?+?"/"?+?e.method); text?+=?line("Id?:?"?+?e.id); text?+=?line("Message?:?"?+?e.message); e?=?e.previous; } return?text; } private?String?line(String?s)?{ return?s?+?separator; } } |
我們來一個個看看這些東西:
在這個繼承了Exception類的自定義異常類中,我們定義了如下變量:
id:獨立標示符,這個是用來進行標示類中什么地方出現了錯誤被捕捉到。
classname:捕捉到這個錯誤的類的名字。
method:捕捉到這個錯誤的方法的名字。
message:用來描述整個事件的情況。
previous:是MyException得一個實例,若在鏈表中它是第一個的話,那么它就是null。
我們再看看都定義了什么方法:
traceBack():產生一個包含在異常類中存儲的數據的一個回溯。使用newline標示作為分隔符
traceBack(String sep):和上一個其實是相同的東西,使用的分隔符可以自己定義。
line(String s):traceBack使用的一個方法。
步驟一:先扔出第一個異常:
這有兩種情況:
a.若程序判斷異常的某個地方主動拋出異常,那么你就會主動拋出一個錯誤,例如:
????? throw?new?MyException(?1,?"Person",?"getSalary", "Trying?to?get?a?salary,?but?no?person?was?specified",null); |
b.在另一個異常出現時拋出該異常,例如:
???? catch?(Exception?e)?{ throw?new?MyException(4,?"Person",?"read",?e.toString(),?null); } |
要是某一個方法要拋出MyException異常,那么在方法定義的時候形式如下:
public void read() throws MyException . . .
步驟二:接著我們扔出來的異常,例如:
Person?p?=?new?Person(); p.setPersonId(id); try?{ p.read(); s?+=?p.getSalary(); } catch?(MyException?e)?{ throw?new?MyException(1,?"Stats",?"getAllSalaries", "Could?not?get?salary?for?"?+?id,?e); } |
我們的策略是這樣的:將我們可能扔出異常的方法置于我們的監控之下(try{}),然后出了事情我們在處理區(catch{})把這個異常處理,至于處理的方式可以是當場處理,也可以處理不了交予其他地方處理(throw())。需要注意的是,我們看到最后一個參數e,我們要在每個新的異常處將這個異常加入到異常類的鏈表中。
步驟三:回溯異常
我們上邊設計的這個異常最后得出的一個異常鏈如下:
???? Calling?sequence?(top?to?bottom) --level?1-------------------------------------- Class/Method:?SalaryServlet/doGet Id?:?7 Message?:?Trying?to?get?the?total?salary?for?employees --level?2-------------------------------------- Class/Method:?Stats/getAllSalaries Id?:?1 Message?:?Could?not?get?salary?for?Lincoln --level?3-------------------------------------- Class/Method:?Person/read Id?:?3 Message?:?java.sql.SQLException:?[HANSEN]Invalid?object?name?'xEMPLOYEE'. --level?4-------------------------------------- Class/Method:?Person/read Id?:?999 Message?:?SQLException.?State/error?code:?S0002/208 |
我們可以分析得知在這個場景上,一個servlet被觸發了,它調用了getAllSalaries,然后又調用了read方法,在read方法中,出現了一個SQLException