Android中关于JSONObject中和Long字段相关的记录
程序员文章站
2022-07-15 13:17:50
...
以下所指的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中的值不一致;
总结一下形成坑的条件:
1. json中使用string类型返回long值 {“id”,”123456789987654321”}
2. json中string的值超过16位
3. 使用JSONObject#getLong或optLong解析
解决方案:
1. String temp = jsonObject.getString(“id”);
2. long id = Long.valueOf(temp);
特别说明,JSONArray同样存在这个问题。
以上。
参考:
https://blog.csdn.net/u013040819/article/details/72566277
https://www.jianshu.com/p/802184bae84b