自定義異常和帶你與太陽肩并肩的神器

java零基礎(chǔ)入門-高級特性篇(十) 異常 下

除了系統(tǒng)定義好的異常,在實(shí)際工作中,會需要按照業(yè)務(wù)邏輯定義各種自定義異常,特別是明確的知道某些情況下需要拋出指定異常的時(shí)候。因?yàn)橄到y(tǒng)定義的異常有時(shí)候不能滿足實(shí)際工作的需要。

自定義異常

現(xiàn)在有一個(gè)任務(wù),編寫一個(gè)工具,包含兩個(gè)方法,一個(gè)是根據(jù)參數(shù)注冊用戶,一個(gè)是根據(jù)注冊的順序獲得用戶信息。這個(gè)工具是提供給其他人用的,也就是說,用工具的人不需要知道工具內(nèi)部的邏輯,只需要按規(guī)矩辦事即可得到結(jié)果。這樣的好處是程序員B在使用工具的時(shí)候完全可以直接使用工具,不需要了解工具是如何編寫如何運(yùn)行的,但是這也會帶來一個(gè)問題,如果工具出了錯(cuò),該怎么辦?如果直接將錯(cuò)誤信息拋給使用者,也就是讓程序員B看錯(cuò)誤信息,由于使用者不了解工具的源代碼,可能排查錯(cuò)誤會十分困難。所以在寫工具的時(shí)候,對異常進(jìn)行“包裝”,返回給使用者一個(gè)一目了然的錯(cuò)誤信息,才是最好的方法。

使用工具

這三個(gè)類大概是上圖中的關(guān)系,一個(gè)類是工具使用者CustomExceptionDemo。兩個(gè)是工具提供者,其中UserTool是工具方法,CustomException是自定義異常類。在提供工具的過程中,不可避免的需要對異常進(jìn)行處理,比如在注冊用戶的時(shí)候要考慮如果用戶輸入的年齡超出正常的年齡怎么辦?需要獲取的用戶不存在怎么辦?發(fā)生異常怎么辦?

自定義異常

先看自定義異常的類CustomException。定義一個(gè)自定義異常首先就是要繼承Exception,因?yàn)槔^承了Exception這個(gè)自定義的異常才能被系統(tǒng)識別為異常,才能有異常的特性,比如被捕獲或者拋出。然后在自定義異常中實(shí)現(xiàn)兩個(gè)構(gòu)造器,但是這兩個(gè)構(gòu)造器都是直接調(diào)用父類的構(gòu)造器。

工具方法

逐段看這個(gè)工具類。首先是registerUser這個(gè)方法,用來注冊用戶。這里成功的話只是打印了一條注冊成功的信息,實(shí)際情況可能會在這里做將用戶信息寫入數(shù)據(jù)等操作。如果用戶的年齡信息小于0或者大于150,這個(gè)情況是不應(yīng)該存在的,所以需要手動拋出異常,但是java中又沒有一個(gè)叫做“用戶年齡錯(cuò)誤”的異常,這里就可以使用自定義異常。由于自定義異常有一個(gè)構(gòu)造器是帶參數(shù)的,并且直接調(diào)用了Exception的構(gòu)造器,所以這里可以直接使用構(gòu)造器創(chuàng)建一個(gè)異常信息。

再來看內(nèi)部類User,這里只是來復(fù)習(xí)一下前面的知識,單獨(dú)定義一個(gè)User類是完全可以的。這個(gè)內(nèi)部類包含了年齡和姓名的屬性。

最后看getUserByNo這個(gè)方法。這個(gè)方法可以理解成根據(jù)用戶注冊的順序獲取用戶,這里為了演示方便,在方法中直接定義了兩個(gè)User對象,然后將這兩個(gè)對象加入集合。當(dāng)使用者使用工具的時(shí)候,傳入的是用戶的順序,獲取到該用戶的名稱。那么問題出現(xiàn)了,這里只有2個(gè)用戶,也就是可以通過下標(biāo)0,1來獲取,但是一旦用戶傳入的是2,集合就會報(bào)錯(cuò)。所以這里判斷了順序參數(shù)和集合的數(shù)量,如果獲取的下標(biāo)超過了集合中最后一個(gè)元素的下標(biāo),需要手動拋出一個(gè)自定義異常,并且指定信息“指定順序用戶不存在”。因?yàn)槿绻粧伋鲎远x異常,而是系統(tǒng)自己拋異常,會拋出下標(biāo)越界的異常,對于調(diào)用者來說,這個(gè)異常的排查會非常困難。

使用者

看使用工具的地方,第一個(gè)方法沒有錯(cuò)誤,輸出的是“注冊成功”。第二個(gè)方法會報(bào)錯(cuò),因?yàn)樵诠ぞ哳愔?,只模擬了2個(gè)用戶的集合,因此這里獲取下標(biāo)為3的用戶會拋出下標(biāo)越界的異常。但是按照上面分析過的問題,如果直接拋出的是下標(biāo)越界使用者排查問題難度很大,而使用自定義異常則可以明確的告訴使用者,是該用戶不存在。這就是使用自定義異常的好處。

自定義異常除了繼承Exception,還可以繼承Exception的子類,比如Runtimeexception。在工作中可以根據(jù)實(shí)際情況,具體選擇要使用的子類來創(chuàng)建自定義異常。

常見異常,下標(biāo)越界和空指針

下面來看兩個(gè)最常見的異常是如何產(chǎn)生的,在后面的學(xué)習(xí)過程中,碰到這樣的異常了解其原因,解決起來會方便很多。

下標(biāo)越界異常

這個(gè)異常最常出現(xiàn)在使用數(shù)組和集合的過程中,因?yàn)樗麄兌伎梢酝ㄟ^下標(biāo)來訪問元素。但是一旦指定的下標(biāo)沒有元素,就會發(fā)生下標(biāo)越界的異常。所以在使用數(shù)組和集合的時(shí)候,一定要注意在使用時(shí),不要訪問沒有元素的下標(biāo)。

下標(biāo)越界

再來看看源代碼,不要怕,你能看懂。

源代碼

首先看這個(gè)異常類,IndexOutOfBoundsException繼承了Exception的子類RuntimeException,然后創(chuàng)建了兩個(gè)構(gòu)造器。等等,是不是有點(diǎn)眼熟,為什么感覺和上面例子中我們自定義的異常幾乎一樣?再來看看拋出異常的地方,在rangeCheck方法中,比較完下標(biāo)和集合長度后拋出異常,跟我們上例中的用法也十分類似。其實(shí),這些異常在java看來,就是java自己的“自定義異常”,我們其實(shí)是在使用java提供的工具,也就是說我們是調(diào)用者,java定義自己的異常,告訴我們(調(diào)用者)異常的錯(cuò)誤信息。

空指針異常

NullPointerException空指針異常,通常是使用對象調(diào)用方法或者屬性的時(shí)候出現(xiàn)的,而這個(gè)對象如果是null就會出現(xiàn)空指針異常。

空指針

看了這個(gè)例子,各位是不是會覺得“你以為我傻呀,我怎么會給對象賦值null”。其實(shí)這里主要表達(dá)的是出現(xiàn)異常的原因,而對象為空的情況會有很多,比如注釋掉的代碼,如果此對象是另一個(gè)方法的返回值,是通過查詢數(shù)據(jù)庫得來的,那么它完全有可能是null。這種情況也是最常見的,因?yàn)闆]有顯式的賦值給對象null,但是如果數(shù)據(jù)查不到,最后賦值給對象的恰恰又是個(gè)null,如果沒有檢查對象是否為null就直接使用,就會發(fā)生空指針異常。

工作中如何處理異常? ??

在實(shí)際的工作中,由于有各種各樣框架的加持,其實(shí)在處理異常的時(shí)候是跟常規(guī)處理方式有些許區(qū)別的。比如前面有說過spring這個(gè)大管家,這里簡單介紹一下,一旦把異常交給管家來管理,我們該如何使用異常。

寫代碼講究的是思想,好的代碼講究的是低耦合,無侵入,這也是大家應(yīng)該追求的境界。在spring中,就提供了很多類似的工具,比如spring中的全局異常處理,就做到了低耦合,無侵入。什么是低耦合,無侵入?想象一下,你的代碼有30個(gè)類,100個(gè)方法,每個(gè)方法都捕獲了異常,當(dāng)發(fā)生異常的時(shí)候打印日志-“程序報(bào)錯(cuò)了!”。你辛辛苦苦復(fù)制粘貼了100遍啊100遍,然后老板有天心情不太好,給我改!改成“程序罷工啦~”。老板一句話,你又得找到那100個(gè)方法,再來復(fù)制粘貼100遍啊100遍,是不是生無可戀?生不如死?

耦合度高,就是依賴度高,關(guān)系緊密,密不可分,同樣的邏輯可以提取成方法,可是異常沒法提取啊,只能復(fù)制粘貼了。

侵入式代碼,就是在業(yè)務(wù)邏輯中加入太多無關(guān)業(yè)務(wù)的代碼,比如異常處理,如果能保證在寫業(yè)務(wù)的時(shí)候完全不需要考慮異常那該多好!

你的夢想,spring為你實(shí)現(xiàn)了,spring簡直就是業(yè)界良心,擼碼神器啊。目前講解spring還太早,但是可以先體會一下這個(gè)框架為我們帶來的幸福生活。

全局異常

以上是spring的全局異常處理方式,管家功能強(qiáng)大,除了全局異常處理,還有別的方法處理異常,更加詳細(xì)的知識可以在各位學(xué)習(xí)spring框架后再作了解。

最后再吹一波,spring這么強(qiáng)大,簡直就是 ---? 帶你飛上天,與太陽肩并肩~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容