国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

使用 JSONObject 需要注意避免的一個問題

sutaking / 503人閱讀

摘要:作者介紹鮑協浩,小米部門,基礎應用組通訊錄開發負責人問題現象在業務同步的邏輯代碼中,使用到了來解析服務端的數據。

作者介紹:鮑協浩,小米MIUI部門, MIUI基礎應用組通訊錄開發負責人

問題現象

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

問題排查

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

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

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

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

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

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

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

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

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

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

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

問題解決

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

問題后話

類似的問題在網上隨意一搜,其實有許多人遇坑了,比如這個。所以,盡管不能說這個庫的設計是很失敗的,但肯定不算是一個設計良好的庫。因為你無法直接從 API 名稱看出內在的潛在邏輯,導致使用不當。因此,經驗教訓就是:使用第三方庫的時候,能看 API 文檔就看 API 文檔,切不可望文生義。

當然,Github 上最新的 JSON-Java 庫是沒有這個問題的。

小米開放平臺重磅推出小米帳號接入有禮活動:成功接入小米帳號即可獲得小米開放平臺免費提供的平臺資源(小米應用商店、小米卡包、小米推送vip、小米帳號聯盟等資源),機會不容錯過,我們期待您的加入!
活動報名地址:http://dev.xiaomi.com/console...

官方QQ交流群:398616987
想要了解更多?
那就關注我們吧!

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/86615.html

相關文章

  • poi幾多愁,恰似源碼溫柔

    摘要:拿到值后,創建當前單元格,把數據填充進去。首先判斷當前單元格的數據是不是數字型的,如果是數字型的,在判斷是不是日期類型的,如果是日期類型,再轉為日期類型。 導讀 最近,公司在做導入導出的項目,首先想到的是poi的導入和導出。如果每次導入和導出都要重寫的話,那么,實在是浪費時間和精力。于是,封裝了原生的poi的導入和導出。在封裝的時候,就會出現一系列的問題。 在進行導入和導出的時候,我們...

    zhiwei 評論0 收藏0
  • Java 編程:如何提高性能?(簡單總結篇)

    摘要:開發者在編程中除了要有編程規范,還要注意性能哦,今天就工作中遇到的一些問題進行了一個簡單總結,希望攻城獅來批評指正。 開發者在編程中除了要有編程規范,還要注意性能,在 Java 編程中有什么提高性能的好辦法呢? 本文轉自國內 ITOM 行業領軍企業 OneAPM Cloud Insight(一款能夠優雅監控多種操作系統、數據庫、中間件、云主機的解決方案)美女工程師陳永梅簡書。 開發者在...

    fuchenxuan 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<