中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用JSONObject需要注意避免什么問題

發布時間:2021-12-04 11:47:50 來源:億速云 閱讀:142 作者:小新 欄目:移動開發

這篇文章給大家分享的是有關使用JSONObject需要注意避免什么問題的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

問題現象

在 Android 業務同步的邏輯代碼中,使用到了 JSONObject 來解析服務端的 JSON  數據。同時本地因為業務新增需求的緣故,在本地數據庫中使用 JSONObject 緩存了包括水位等同步相關的信息,其中,水位值是 Long  型。但近期發現同步過程中下一次同步時,傳遞給服務器的水位并不是上一次服務器返回的新水位,而是相差一些。以 301028292893495297L  為例,服務器返回這個水位之后,下次客戶端上傳的水位是 301028292893495296L,差值為 -1。

問題排查

通過反復排查代碼邏輯,發現水位從服務端返回到下次請求之間,只經過了以下轉換:

使用JSONObject需要注意避免什么問題

認真閱讀代碼不難發現,Long 型的水位值保存在 JSON 對象中的時候轉成了 String 型,而在讀取的時候又當作是 Long  型來處理。因此會有精度缺失的問題,參見如下 JSONObject 的文檔:

由此可見,在讀取 JSON 對象的某個值時,如果原先是 String 型,讀取的時候當作是 Long 型,是會將 String 型通過 Double  進行解析的,所以在值超過 2^52 時會有精度缺失的問題。于是,遇到的問題就可以解釋了。以下是 Double 的存儲格式規范:

使用JSONObject需要注意避免什么問題

其中,Double 和 Long 的精度測試代碼很簡單(輸入參數可以提供例如 301028292893495297L 這樣超過 2^52 的 long  值,會發現其返回值不為 0):

使用JSONObject需要注意避免什么問題

Double 和 Long 的精度測試代碼很簡單(輸入參數可以提供例如 301028292893495297L 這樣超過 2^52 的 long  值):

知道了問題的根源,修復就一目了然了,在水位保存在 JSONObject 對象中時,應該當作 Long 型而不是 String  型來保存;亦或者在讀取的時候也當作是 String 型,然后通過 Long.valueOf 等接口進行解析。

另外,關于 JSON 對象中的值是 Long 型還是 String 型,其實比較容易被忽略。如果JSON 對象在使用 String  表示的時候,該值對應處有引號就是 String 型。看如下的試用例就一目了然了:

使用JSONObject需要注意避免什么問題

類似的問題在網上隨意一搜,其實有許多人遇坑了,比如這個。

所以,盡管不能說這個庫的設計是很失敗的,但肯定不算是一個設計良好的庫。因為你無法直接從 API  名稱看出其內在的潛在邏輯,容易導致使用者使用不當。因此,經驗教訓就是:使用第三方庫的時候,能看 API 文檔就看 API  文檔,切不可望文生義。當然,這個問題可能也僅限在 Android 中較老的代碼模塊,畢竟新的代碼都會使用 GSON 等類庫進行 JSON  對象操作,也就不容易出現這樣的不易發現的問題了。

當然,單就這個問題來看,其實是在新增業務邏輯的時候,沒有正確使用 JSONObject 對象的接口,Long 型的值不應當看成是 String  型進行保存而又當成是 Long 型來讀取,如果保存和讀取的接口保持對應,也就不會出現問題了。不管怎么說,該問題的教訓是在使用 JSONObject  相關接口時要倍加小心謹慎。

備注:Github 上***的 JSON-Java 庫沒有這個問題,可以放心使用。

使用JSONObject需要注意避免什么問題

問題解決

知道了問題的根源,修復就一目了然了,在水位保存在 JSON 對象中時,應該當作 Long 型而不是 String 型來保存;或者在讀取的時候也當作是  String 型,然后通過 Long.valueOf 等接口進行解析。

感謝各位的閱讀!關于“使用JSONObject需要注意避免什么問題”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

邵东县| 中宁县| 瑞安市| 楚雄市| 桦甸市| 博客| 千阳县| 哈巴河县| 康保县| 乡城县| 三台县| 孝昌县| 梅河口市| 哈巴河县| 东明县| 江孜县| 理塘县| 和平区| 永定县| 罗定市| 吐鲁番市| 乌海市| 昭通市| 呼玛县| 江川县| 华池县| 宝坻区| 宁陕县| 尼勒克县| 沙雅县| 中西区| 绵阳市| 高唐县| 布尔津县| 寿光市| 罗田县| 商水县| 连城县| 新晃| 印江| 新化县|