Java異常之自定義異常
哎呀,媽呀,又出異常了!俗話說:“程式碼虐我千百遍,我待程式碼如初戀”。
小Alan最近一直在忙著工作,已經很久沒有寫寫東西來加深自己的理解了,今天來跟大家聊聊Java異常。Java異常的體系什麼的,理論知識啥的我就懶得去BB太多了,是個搞Java開發的都知道,只是可能理解的不深,這個大家可以自己多看看資料,我就簡單的說說。
什麼是異常?
我不知道大家都是怎麼去理解的,我的理解很簡單,那就是不正常的情況,比如我現在是個男的,但是我卻有著女人所獨有的東西,在我看來這尼瑪肯定是種異常,簡直不能忍。就拿上面的異常圖片來說,你應該是有小弟弟的,但你卻沒有小弟弟,這就是不正常的情況了,所以Java這個妹子會告訴你,你應該有小弟弟的才能辦事,或者你沒小弟弟就別來辦事,你沒小弟弟也要強上別人,那也沒法玩啊是吧?
常說我們人的祖宗是猿,異常Exception的祖宗那就是Throwable類了,除了Exception類外,Throwable還有一個子類Error 。Error這玩意就不說了,你如果遇到了它你可以把電腦砸了,呼呼呼...跟大家開個玩笑,反正這玩意不是我們程式能處理的,它在程式處理的範疇之外。至於異常Exception又分為傻傻啥的,我就不BB了,再BB就B到這上面了。
給大家隨便列舉幾個異常:
RuntimeException:你不能跑得足夠快,可能因為你太胖了。關掉你的電腦,出門鍛鍊吧。
NullPointerException:你沒有狗。請你先找一隻狗,比如一隻布烈塔尼獵犬,然後再試一次。
IndexOutOfBoundsException:你把食指放在了無法接收的地方,重新放置,再試一次。
FileNotFoundException:一名木匠應該總是知道他的工具放在哪裡。
NotSerializableException:你正試圖把一部電影改成電視劇。
這尼瑪什麼鬼?反正我是沒看懂。還好今天我要理解的物件不是上面的這些玩意,搞錯物件就不好了,看看就好了,但是別亂搞,男人都懂的,嘖..嘖..嘖...。
自定義異常
今天我們要來理解的是什麼是自定義異常,為什麼要使用自定義異常,使用自定義異常有哪些好處,有哪些不好的地方?
要使用自定義異常就跟你和女朋友相處一樣的,首先你得知道你為什麼要跟你女朋友在一起,你女朋友有哪些好處,有哪些不好的地方,再來和你女朋友談婚論嫁過一輩子,我們就先來說說這些問題,最後再來看怎麼使用自定義異常,自定義異常的實現和使用非常簡單,關鍵還是理解why的內容。
為什麼要使用自定義異常,有什麼好處?
1.我們在工作的時候,專案是分模組或者分功能開發的 ,基本不會你一個人開發一整個專案,使用自定義異常類就統一了對外異常展示的方式。
2.有時候我們遇到某些校驗或者問題時,需要直接結束掉當前的請求,這時便可以通過丟擲自定義異常來結束,如果你專案中使用了SpringMVC比較新的版本的話有控制器增強,可以通過@ControllerAdvice註解寫一個控制器增強類來攔截自定義的異常並響應給前端相應的資訊(關於springMVC控制器增強的知識有空再和大家分享)。
3.自定義異常可以在我們專案中某些特殊的業務邏輯時丟擲異常,比如"中性".equals(sex),性別等於中性時我們要丟擲異常,而Java是不會有這種異常的。系統中有些錯誤是符合Java語法的,但不符合我們專案的業務邏輯。
4.使用自定義異常繼承相關的異常來丟擲處理後的異常資訊可以隱藏底層的異常,這樣更安全,異常資訊也更加的直觀。自定義異常可以丟擲我們自己想要丟擲的資訊,可以通過丟擲的資訊區分異常發生的位置,根據異常名我們就可以知道哪裡有異常,根據異常提示資訊進行程式修改。比如空指標異常NullPointException,我們可以丟擲資訊為“xxx為空”定位異常位置,而不用輸出堆疊資訊。
說完了為什麼要使用自定義異常,有什麼好處,我們再來看看自定義異常的毛病:
毋庸置疑,我們不可能期待JVM(Java虛擬機器)自動丟擲一個自定義異常,也不能夠期待JVM會自動處理一個自定義異常。發現異常、丟擲異常以及處理異常的工作必須靠程式設計人員在程式碼中利用異常處理機制自己完成。這樣就相應的增加了一些開發成本和工作量,所以專案沒必要的話,也不一定非得要用上自定義異常,要能夠自己去權衡。
最後,我們來看看怎麼使用自定義異常:
在 Java 中你可以自定義異常。編寫自己的異常類時需要記住下面的幾點。
- 所有異常都必須是 Throwable 的子類。
- 如果希望寫一個檢查性異常類,則需要繼承 Exception 類。
- 如果你想寫一個執行時異常類,那麼需要繼承 RuntimeException 類。
可以像下面這樣定義自己的異常類:
class MyException extends Exception{ }
我們來看一個完整的例項:
1 package com.czgo.exception; 2 3 /** 4 * 自定義異常類(繼承執行時異常) 5 * @author AlanLee 6 * @version 2016/11/26 7 */ 8 public class MyException extends RuntimeException { 9 10 private static final long serialVersionUID = 1L; 11 12 /** 13 * 錯誤編碼 14 */ 15 private String errorCode; 16 17 /** 18 * 訊息是否為屬性檔案中的Key 19 */ 20 private boolean propertiesKey = true; 21 22 /** 23 * 構造一個基本異常. 24 * 25 * @param message 26 * 資訊描述 27 */ 28 public MyException(String message) 29 { 30 super(message); 31 } 32 33 /** 34 * 構造一個基本異常. 35 * 36 * @param errorCode 37 * 錯誤編碼 38 * @param message 39 * 資訊描述 40 */ 41 public MyException(String errorCode, String message) 42 { 43 this(errorCode, message, true); 44 } 45 46 /** 47 * 構造一個基本異常. 48 * 49 * @param errorCode 50 * 錯誤編碼 51 * @param message 52 * 資訊描述 53 */ 54 public MyException(String errorCode, String message, Throwable cause) 55 { 56 this(errorCode, message, cause, true); 57 } 58 59 /** 60 * 構造一個基本異常. 61 * 62 * @param errorCode 63 * 錯誤編碼 64 * @param message 65 * 資訊描述 66 * @param propertiesKey 67 * 訊息是否為屬性檔案中的Key 68 */ 69 public MyException(String errorCode, String message, boolean propertiesKey) 70 { 71 super(message); 72 this.setErrorCode(errorCode); 73 this.setPropertiesKey(propertiesKey); 74 } 75 76 /** 77 * 構造一個基本異常. 78 * 79 * @param errorCode 80 * 錯誤編碼 81 * @param message 82 * 資訊描述 83 */ 84 public MyException(String errorCode, String message, Throwable cause, boolean propertiesKey) 85 { 86 super(message, cause); 87 this.setErrorCode(errorCode); 88 this.setPropertiesKey(propertiesKey); 89 } 90 91 /** 92 * 構造一個基本異常. 93 * 94 * @param message 95 * 資訊描述 96 * @param cause 97 * 根異常類(可以存入任何異常) 98 */ 99 public MyException(String message, Throwable cause) 100 { 101 super(message, cause); 102 } 103 104 public String getErrorCode() 105 { 106 return errorCode; 107 } 108 109 public void setErrorCode(String errorCode) 110 { 111 this.errorCode = errorCode; 112 } 113 114 public boolean isPropertiesKey() 115 { 116 return propertiesKey; 117 } 118 119 public void setPropertiesKey(boolean propertiesKey) 120 { 121 this.propertiesKey = propertiesKey; 122 } 123 124 }
使用自定義異常丟擲異常資訊:
1 package com.czgo.exception; 2 3 public class MyExceptionTest { 4 5 public static void main(String[] args) { 6 7 String[] sexs = {"男性","女性","中性"}; 8 for(int i = 0; i < sexs.length; i++){ 9 if("中性".equals(sexs[i])){ 10 throw new MyException("你全家都是中性!"); 11 }else{ 12 System.out.println(sexs[i]); 13 } 14 } 15 } 16 }
執行結果:
就是這麼簡單,我的話實現了很多建構函式,可以根據實際業務需求去丟擲相應的自定義異常。
結束語:現在搞軟體開發的人越來越多了,高手數不勝數,菜鳥也數不勝數,把這行的行情攪的比較混亂。所以初入這行的哥們一定要有危機意識。公司都想要工資開的不高,又能做一大把事情的人,搞開發很累,但是在當前的環境下,一定要不斷的去提高自己。到了洗牌的時候,可能被淘汰的人裡面就有你,除非你去做別的,不然就硬著頭皮幹幾年把技術搞紮實,該複習的知識就多多複習,該學習的知識就多多學習,基礎紮實了就去看看底層的東西,比如理解理解Java虛擬機器,研究研究Spring原始碼。多關注關注前沿技術的發展,因為你現在所用的東西或許某一天大部分公司就不用了,或者根本滿足不了專案的需求,這都是有可能的。希望大家都能混出自己的一片天地,小Alan現在也還在吃土中,所以大家都在一起前行,這世界終究是屬於年輕人的,彆氣餒。
可愛博主:AlanLee
本文出自部落格園,歡迎大家加入部落格園。