近期發現公司同事在使用Gson對數字進行反序列列化時出現丟失精度的問題,在這里搬運一下,做個記錄~
現象
使用Gson反序列化長Long數字(大于16位),如果用Object類型來接收則會丟失精度。
Gson會將數字反序列化為double類型,double類型本身就容易丟精度。(精度丟失原因可自行搜索)
再轉回Long時就會導致數據異常
根因
Gson在把數字反序列為Object時,默認會轉換成Double。
可以看Gson的ObjectTypeAdapter類
碰到數字類型時,會調用toNumberStrategy。
如果你的Gson低于2.8.9,這里就不會使用toNumberStrategy。
直接是in.nextDouble();
這個toNumberStrategy是構建Gson對象時傳入的,在Gson2.8.9中默認是Double策略
所以,Gson在把數字反序列為Object時,默認會轉換成Double。
而超過16位的數字轉成Double,精度就會丟失導致數據不正確。
解決辦法
1.盡量避免用Object來接收大數字,最好使用字符串String接收
2.如果你非要用Object。那就修改Gson反序列化Object時候的策各吧(需要Gson版本>=2.8.9)
在GsonBuilder中有一個方法setObjectToNumberStrategy(),建議改成BigDecimal策略一勞永逸。