以下所指的JSONObject均爲org.json.JSONObject;
get系方法和opt系方法區別
-
get系方法在key不存在時候會拋受檢異常(JSONException)
-
opt系方法在key不存在時候會返回默認值
源碼:
這裏nameValuePairs類型爲LinkedHashMap。
getLong或optLong可能導致的長整型精度丟失
通過源碼可知, 不論是getLong還是optLong最終都會走
JSON.toLong(object);
該方法源碼:
static Long toLong(Object value) {
if (value instanceof Long) {
return (Long) value;
} else if (value instanceof Number) {
return ((Number) value).longValue();
} else if (value instanceof String) {
try {
return (long) Double.parseDouble((String) value);
} catch (NumberFormatException ignored) {
}
}
return null;
}
重點在這句強轉:
return (long) Double.parseDouble((String) value);
重點在於: parseDouble(String)沒辦法保證在String超過16位數以後的精度
這樣一個強轉就有可能造成JSONObject#getLong或optLong的返回值和原json中的值不一致;
總結一下形成坑的條件:
- json中使用string類型返回long值 {“id”,“123456789987654321”}
- json中string的值超過16位
- 使用JSONObject#getLong或optLong解析
解決方案:
- String temp = jsonObject.getString(“id”);
- long id = Long.valueOf(temp);
特別說明,JSONArray同樣存在這個問題。
以上。
參考:
https://blog.csdn.net/u013040819/article/details/72566277
https://www.jianshu.com/p/802184bae84b