最近在寫CRUD
的時候,發現有個分頁的VO
寫的健壯性比較差,一時手癢改了一下,沒想到改了以後好幾個功能都出現了問題。前端
原VO
關鍵代碼以下:apache
public class PageVo implements Serializable{ // ...省略全部無關代碼 Map<String, String> query }
這個VO
是用於從前端分頁查詢時傳參,而query
是用於傳遞查詢條件的(這裏不討論用Map
傳參是否合理)。當前端無查詢條件時則會致使query
爲null
,若是不注意容易出現NPE
。數組
因此我就改形成下面這樣了。工具
public class PageVo implements Serializable{ // ...省略全部無關代碼 Map<String, String> query=new HashMap<> }
可是沒想到就是這麼簡單的改造竟然都翻車(・ε・`)源碼分析
沒辦法,只好去排查問題。this
想過不少種緣由,可是我真沒想到竟然是由於這樣(/‵Д′)/~ ╧╧,很少說了,問題關鍵代碼以下:設計
if (StringUtils.isEmpty(page.getQuery())) { // 省略處理邏輯 }
竟然用StringUtils
去判斷一個Map
是否爲空,好歹也換個CollectionUtils
啊(╬ ̄皿 ̄)凸code
雖然是前人挖坑,可是爲何Spring
的`StringUtils
竟然設計成支持Object
入參呢o_o ....對象
想了一下,仍是去看看源碼吧get
StringUtils
的isEmpty()
方法源碼超級簡單,三行代碼搞定(其實嚴格來講就一行代碼):
public static boolean isEmpty(@Nullable Object str) { return (str == null || "".equals(str)); }
既然個人Map
對象不爲null
,那麼問題應該是由於String
的equals()
方法。很少說,繼續跟蹤源碼
public boolean equals(Object anObject) { if (this == anObject) { return true; } // 問題出在這裏 if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
這個equals()
方法的邏輯很簡單
null
則返回true
String
類型返回false
this
對象都爲String
就比較它們內置的char[]
數組長度和每一個char
元素是否相同,知足則返回true
,不然返回false
而個人問題就是由第二點引發的,由於類型不相同┴─┴︵╰(‵□′╰)
Spring
的StringUtils
的isEmpty()
對非String
類型的對象判空。(這裏建議換成apache common
的StringUtils
或者Google Guava
的Strings
,這兩個工具包都是類型強約束的)