FastJson會把哪些字串解析為null
前言
改一個別人的bug時遇到的,感覺有點意思。
問題
先看一段程式碼:
public static void main(String[] args) {
String sourceStr = "";
JSONObject jsonObject = JSONObject.parseObject(sourceStr);
System.out.println(jsonObject);
}
問:
- 當sourceStr為null的時候,會報空指標異常嗎?
- 當sourceStr為空字串的時候,會報解析異常嗎?
- 當sourceStr為字串"null"的時候,會報什麼錯誤呢?
程式碼
public static void main(String[] args) { String sourceStr = null; JSONObject jsonObject = JSONObject.parseObject(sourceStr); System.out.println(jsonObject); sourceStr = ""; jsonObject = JSONObject.parseObject(sourceStr); System.out.println(jsonObject); sourceStr = "null"; jsonObject = JSONObject.parseObject(sourceStr); System.out.println(jsonObject); }
上面程式碼的輸出結果:
null
null
null
總結
發現這個問題的原因是有個同事在對字串判空的時候使用的是 if (str == null),但是傳入的str是一個空字串"", 所以後面對解析出來的jsonObject進行操作的時候就出現了空指標。其實現在有很多包中都有StringUtils這種工具類,裡面有isEmpty()這種方法,整合了 (str == null) 和 str.length = 0,一般建議使用這種判空方法,當然也要結合具體的業務場景。
後記
其實我在找這個問題的時候正經花了比較大的功夫,因為中間有一些曲折。。。
先貼一下大致的程式碼:
class JsonUtils { private static final Logger log = LoggerFactory.getLogger(JsonUtils.class); public void test(String sourceStr) { log.info("sourceStr: {}", sourceStr); if (sourceStr == null) { return; } JSONObject jsonObject = JSONObject.parseObject(sourceStr); System.out.println(jsonObject.getString("a")); } }
從上面的程式碼可以看出,sourceStr是一個傳參,我們並不知道它是什麼,但是有log記錄,同時也是這個log讓我走了很長的彎路。
大致流程是這樣的:
-- 發現jsonObject.getString("a") 出現空指標異常,猜測jsonObject為null;
-- 立即問了負責這塊的同事,讓他看一下日誌中的sourceStr列印的是什麼;
-- 同事回覆的列印是: sourceStr: null;
-- 我就開始奇怪了,如果sourceStr是null的話,會直接return,不會走到下面空指標的地方呀;
-- 這個時候我的小腦袋瓜子不知道想到哪兒了,突然覺得難道傳進來的是字串"null"?
-- 我立即寫了程式碼來驗證我的猜想:
public static void main(String[] args) {
JsonUtils.test("null");
}
結果讓我有點意料不到:
sourceStr: null
java.lang.NullPointerException
需要注意的是,log列印的時候,null和字串 "null" 打印出來的結果是一毛一樣的。
-- 難道真的是這個原因??
-- 後來和相關方確認,不可能會傳一個字串"null"進來,到這兒陷入了僵局
-- 於是我親自去找了相應的日誌,發現。。。。。。 告訴我sourceStr是null的那個同事看錯日誌的時間了。。。,他看到sourceStr為null的那些時候,根本就沒有出現空指標異常。出現空指標異常的時候,傳入的sourceStr為空字串""
-- 問題解決。