毫無疑問,空指針NullpointerException是我們最常遇到異常,沒有之一!
在剛進入編程職業時,我想,大部分進入的同學肯定會受到前輩們的叮嚀:一定要防止空指針,這是個低級錯誤。你們不是?好吧,反正我是這樣~
於是乎,在每一個方法中,無論是接收到的參數還是通過其他方法得到的結果,我都會進行空指針判斷,諸如:
1 public boolean isValid(String code){ 2 if(StringUtils.isBlank(code)){ 3 ..... 4 } 5 ..... 6 }
抑或:
1 public boolean isValid(String code){ 2 .... 3 User user= userManager.find(code); 4 if(user==null){ 5 .... 6 } 7 }
這樣並沒有錯誤不是嗎?極大程度上可以預防空指針NullpointerException的發生。
按照這種方式,瘋狂地防止NullpointerException一段時間后,因為業務需要,在已經實現的業務中修改業務邏輯,突然覺得到處都是if防止空指針代碼,原本簡短的業務邏輯代碼隱藏在了這種防止空指針代碼中,有點像電視劇放廣告:以前是電視劇中插播廣告,現在是廣告中插播電視劇。
總之,自己寫的代碼都看的有些暈乎乎,但是,這樣做是沒錯,我也很無奈啊!
經過一段時間,review別人寫的代碼以及參考一些框架源碼,我開始問自己一個問題:NullpointerException真的一定需要被處理嗎?或者說所有的NullpointerException都需要被自己處理嗎?
答案顯然是否定的!
就拿上面的代碼作為例子,第一種情況,如果code為null,經過判斷后返回false,第二種情況,code存在,但是user不存在,同樣返回false。
這樣的邏輯並沒有問題對吧,至少對於這個方法並沒有問題,除了多了一些判空語句。
假設我們去除上面代碼中關於code的判空,並且假設find方法中有對code的處理:按code中的“#”split分成數組。
那么當code為null傳入isValid方法中,因為find方法使用了code的split方法,會報出空指針異常NullpointerException。
我們稍微思考下,這里的NullpointerException會給方法調用方帶去什么影響:方法調用方將知道code是必選的參數,不能為null。
這樣,那方法調用方自己控制傳入的參數不能為null就好了,或者自己加上try/catch處理,isValid有自己的邏輯需要實現,既然你調用我,那么就需要滿足我的要求,而不是我適應方法調用方的需求!
可能例子舉的有些抽象,我整理下主要思想:
- 對於傳入的參數,方法非底層方法,那么只按照自己認定的方式處理。比如我就認為這個參數不為null,並且后續的處理方式有代碼必須要求該參數不可為空,如果為null就會拋出NullpointerException,然后只需要按照不為null的方式處理,不會判斷是否為null;
- 同樣對於傳入的參數,如果方法已經是底層的方法,對該參數不會有不為null的要求,那就需要該方法進行相應空指針判斷了,因為你需要拋出對應的異常信息;
- 如果是調用其他方法得到的結果,如果一定需要不為null的,那么就需要判空,因為你同樣需要拋出對應的異常信息;
可以利用愛情公寓中一句經典台詞來記憶:跟我賭,不是看你要什么而是看我有什么。
放在這,可以改成:有求我,不是看你有什么,而是看我要什么。
這樣做可以明顯減少這些讓人不甚厭煩的判空語句,更好的展現實際的業務邏輯,更易進行維護!!!
思想一例子:
1 public boolean isValid(String code){ 2 String[] arr=code.split("#"); 3 .... 4 }
思想二例子(底層,mybatis按照code查詢user):
1 if(StringUtils.isBlank(code)){ 2 throw new NullPointerException("code不可為空"); 3 } 4 User user=userMapper.findByCode(code); 5 .... 6 }
作者: 風語
因水平限制,本人觀點難免會有錯誤疏漏,如發現有什么不妥或者有更好的建議或意見,還請各位不吝賜教!
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出, 如有問題, 可郵件(1475958950@qq.com)咨詢。