Java自定义异常封装
Java自定義異常封裝
- 前言:異常的分類
- 1.為什么要自定義異常封裝?
- 2.自定義異常封裝有哪些優(yōu)點(diǎn)?
- 2.1 提高系統(tǒng)的友好性
- 2.2 提高系統(tǒng)的可維護(hù)性
- 2.3 解決Java異常機(jī)制自身的缺陷
- 3. 如何進(jìn)行自定義異常封裝?
前言:異常的分類
Throwable包含了錯(cuò)誤(Error)和異常(Excetion兩類)
異常類分為2類:運(yùn)行時(shí)異常(RuntimeException, 又叫非檢查異常)和非運(yùn)行時(shí)異常(又叫檢查異常)
1.運(yùn)行時(shí)異常都是RuntimeException類及其子類,如 NullPointerException、IndexOutOfBoundsException等, 這些異常是不檢查的異常,是在程序運(yùn)行的時(shí)候可能會(huì)發(fā)生的, 所以程序可以捕捉, 也可以不捕捉. 這些錯(cuò)誤一般是由程序的邏輯錯(cuò)誤引起的, 程序應(yīng)該從邏輯角度去盡量避免。
2.非運(yùn)行時(shí)異常是運(yùn)行時(shí)異常以外的異常, 也是Exception及其子類, 這些異常從程序的角度來(lái)說(shuō)是必須經(jīng)過(guò)捕捉檢查處理的, 否則不能通過(guò)編譯. 如IOException、SQLException等。
Error是程序無(wú)法處理了, 如OutOfMemoryError、OutOfMemoryError等等, 這些異常發(fā)生時(shí), java虛擬機(jī)一般會(huì)終止線程。
1.為什么要自定義異常封裝?
Java語(yǔ)言的異常處理機(jī)制可以確保程序的健壯性,提高系統(tǒng)的開發(fā)效率,但是Java API提供的異常都是比較低級(jí)(這里的低級(jí)指的是“低級(jí)別的異常”),只有開發(fā)人員才能看的懂,才明白發(fā)生了什么問(wèn)題。對(duì)于終端用戶來(lái)說(shuō),這些異常基本上是天書,與業(yè)務(wù)無(wú)關(guān),是純計(jì)算機(jī)語(yǔ)言的描述。
這就需要我們對(duì)異常進(jìn)行封裝了。
2.自定義異常封裝有哪些優(yōu)點(diǎn)?
2.1 提高系統(tǒng)的友好性
例如,打開一個(gè)文件,如果文件不存在,則會(huì)報(bào)FileNotFoundException異常,如果該方法的編寫不做任何處理,直接上拋上層,則會(huì)降低系統(tǒng)的友好性,代碼如下所示:
public static void doStuff()throws Exception{ InputStream is = new FileInputStream("無(wú)效文件.txt"); /*文件操作*/ }此時(shí)doStuff方法的友好性極差:出現(xiàn)異常時(shí)(比如文件不存在),該方法直接把FileNotFoundException異常拋出到上層應(yīng)用中(或者是終端用戶),而上層應(yīng)用(或用戶)要么自己處理,要么接著拋出,最終的結(jié)果就是讓用戶對(duì)著“天書”式的文字發(fā)呆,用戶不知道這是什么問(wèn)題,只是系統(tǒng)告訴他”哦,我出錯(cuò)了,什么錯(cuò)誤?你自己看著辦吧“。
解決辦法就是封裝異常,可以把系統(tǒng)的閱讀者分為兩類:開發(fā)人員和用戶。開發(fā)人員查找問(wèn)題,需要打印出堆棧信息,而用戶則需要了解具體的業(yè)務(wù)原因,比如文件太大,不能同時(shí)編寫文件等,代碼如下:
2.2 提高系統(tǒng)的可維護(hù)性
public void doStuff(){ try{ //do something }catch(Exception e){ e.printStackTrace(); } }這是很多程序員容易犯的錯(cuò)誤,拋出異常是吧?分類處理多麻煩,就寫一個(gè)catch塊來(lái)處理所有異常吧。而且還信誓旦旦的說(shuō)”JVM會(huì)打印出棧中的錯(cuò)誤信息“,雖然這沒(méi)有錯(cuò),但是該信息只有開發(fā)人員自己才看的懂,維護(hù)人員看見這段異常基本上無(wú)法處理,因?yàn)樾枰钊氲酱a邏輯中去分析問(wèn)題。
正確的做法是對(duì)異常進(jìn)行分類處理,并進(jìn)行封裝輸出,代碼如下:
如此包裝后,維護(hù)人員看到這樣子的異常就有了初步的判斷,或者檢查配置,或者初始化環(huán)境,不需要直接到代碼層級(jí)去分析了。
2.3 解決Java異常機(jī)制自身的缺陷
Java中的異常一次只能拋出一個(gè),比如,doStuff方法有兩個(gè)邏輯代碼片段,如果在第一個(gè)邏輯片段中拋出異常,則第二個(gè)邏輯片段就不執(zhí)行了,也就無(wú)法拋出第二個(gè)異常了。那么如何才能一次拋出兩個(gè)異常呢?
其實(shí),使用自行封裝的異常可以解決問(wèn)題,代碼如下
MyException異常只是一個(gè)異常容器,可以容納多個(gè)異常,但它本身并不代表任何異常含義,它所解決的是一次拋出多個(gè)異常的問(wèn)題,具體調(diào)用如下:
public static void doStuff()throws MyException{ List<Throwable> list = new ArrayList<Throwable>(); //第一個(gè)邏輯片段 try{ //Do something }catch(Exception e){ list.add(e); } //第二個(gè)邏輯片段 try{ //Do something }catch(Exception e){ list.add(e); } //檢查是否有必要拋出異常 if(list.size() > 0){ throw new MyException(list); } }這樣一來(lái),doStuff方法的調(diào)用者就可以一次獲得多個(gè)異常,也能夠?yàn)橛脩籼峁┩暾睦馇闆r說(shuō)明。
那么在什么情況下,需要一個(gè)方法拋出多個(gè)異常呢?比如Web界面注冊(cè)時(shí),展示層依次把User對(duì)象傳遞給邏輯層,Register方法需要對(duì)各個(gè)Field進(jìn)行校驗(yàn)并注冊(cè),例如,用戶名不能重復(fù),密碼必須符合密碼策略等,不要出現(xiàn)第一次提交系統(tǒng)提示”用戶名重復(fù)“,在修改在提交后,系統(tǒng)提示“密碼長(zhǎng)度少6位”的情況,這種操作模式用戶體驗(yàn)非常糟糕,最好的解決辦法就是封裝異常,建立異常容器,一次性地對(duì)User對(duì)象進(jìn)行校驗(yàn),然后返回所有異常。
3. 如何進(jìn)行自定義異常封裝?
3.1、添加一個(gè)枚舉LuoErrorCode.java如下
package com.luo.errorcode;public enum LuoErrorCode {NULL_OBJ("LUO001","對(duì)象為空"),ERROR_ADD_USER("LUO002","添加用戶失敗"),UNKNOWN_ERROR("LUO999","系統(tǒng)繁忙,請(qǐng)稍后再試....");private String value;private String desc;private LuoErrorCode(String value, String desc) {this.setValue(value);this.setDesc(desc);}public String getValue() {return value;}public void setValue(String value) {this.value = value;}public String getDesc() {return desc;}public void setDesc(String desc) {this.desc = desc;}@Overridepublic String toString() {return "[" + this.value + "]" + this.desc;} }注意!!!這里我們重寫了LuoErrorCode的toString方法,至于為什么要這樣,后面會(huì)提到,客觀請(qǐng)繼續(xù)看。
3.2、創(chuàng)建一個(gè)異常類BusinessException.java,繼承RuntimeException:
package com.luo.exception;public class BusinessException extends RuntimeException {private static final long serialVersionUID = 1L;public BusinessException(Object Obj) {super(Obj.toString());}}這里的代碼雖然短,但是有兩點(diǎn)需要注意的!!!第一點(diǎn)是其繼承了RuntimeException,因?yàn)橐话阄覀兊臉I(yè)務(wù)異常都是運(yùn)行時(shí)異常。第二點(diǎn),這里的構(gòu)造方法調(diào)用父方法super(Obj.toString());,這就是重寫了LuoErrorCode的toString方法的原因了,如果還不明白,看完后面的你就明白了。
3.3、測(cè)試類ExceptionTest.java:
package com.luo.test;import com.luo.errorcode.LuoErrorCode; import com.luo.exception.BusinessException;public class ExceptionTest {public static void main(String args[]) {Object user = null;if(user == null){throw new BusinessException(LuoErrorCode.NULL_OBJ);}} }運(yùn)行結(jié)果:
在我們實(shí)際項(xiàng)目里面,比如別人調(diào)用你接口,你可能需要先看他傳過(guò)來(lái)的對(duì)象是不是空的,先判斷如果傳過(guò)來(lái)的對(duì)象為空給有友好的提示”[LUO001]對(duì)象為空”,不然后面的代碼估計(jì)會(huì)出現(xiàn)空指針異常了。
一般公司都會(huì)分裝一個(gè)基礎(chǔ)框架,異常分裝是其中一部分,當(dāng)然他們對(duì)異常的分裝肯定比我這個(gè)例子復(fù)雜多,因此本例僅供參考!
原創(chuàng):
https://blog.csdn.net/qq_34309305/article/details/79202929
https://blog.csdn.net/u014754272/article/details/104765665
https://www.jianshu.com/p/a874e5d1bed1
總結(jié)
以上是生活随笔為你收集整理的Java自定义异常封装的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C4D如何编辑旋转贴图?
- 下一篇: java怎样做倒计时,Java 中怎么实